JSX 语法

App 组件

  1. function App() {
  2. return (
  3. <div className="App">
  4. 你好 <button>xxx</button>
  5. </div>
  6. );
  7. }
  8. export default App;
  • 以上代码会被 babel-loader 转换

    1. function App() {
    2. return React.createElement('div', // 元素标签名
    3. {className:"App"}, // 元素属性、事件
    4. ['你好'React.createElement('button',{},'xxx')]) // 子元素

    引入组件

    1. ReactDOM.render(
    2. <App/>, // 等同于 App()
    3. document.getElementById('root') // 挂载
    4. )

    条件判断

    1. function App() {
    2. return (
    3. <div>
    4. { n/2 === 0 ? 你好 : <button>xxx</button> } // 三目运算符
    5. </div>
    6. );
    7. }
    8. export default App;

    循环

    1. function App(props) {
    2. return (
    3. props.numbers.map( (item,index)=>{
    4. return <div key={index}>{index}>item:{item} | index:{index}</div>
    5. })
    6. // 加 div 包裹 需要加 {}
    7. <div>
    8. { props.numbers.map( (item,index)=>{
    9. return <div key={index}>{index}>item:{item} | index:{index}</div>
    10. })
    11. }
    12. </div>
    13. );
    14. }
    15. export default App;

    React.Fragment

  • React.Fragment 组件能够在不额外创建 DOM 元素的情况下,让 render() 方法中返回多个元素。

  • 简写语法:<></>

    1. render() {
    2. return (
    3. <React.Fragment>
    4. <h2>A heading</h2>
    5. <div></div>
    6. </React.Fragment>
    7. );
    8. }

    组件

  • 返回一个 React 元素的函数或类

    函数组件

    ```javascript function Hello(props) { // Hello 组件 return (

    1
    ) } const Hello = props =>
    1
    // 简写

function App() { // App 组件 return (

) }

  1. <a name="mbWAu"></a>
  2. ### 类组件
  3. ```javascript
  4. import React from 'react' // Hello 组件
  5. class Hello extends React.Component {
  6. render() {
  7. return ( <h1></h1> )
  8. }
  9. }
  10. class App extends React.Component { // App 组件
  11. render() {
  12. return ( <div>
  13. <Hello />
  14. </div>
  15. )
  16. }
  17. }

props (外部数据)

函数

  1. function App() { // App 组件
  2. return ( <div>
  3. <Hello name='frank'>你好</Hello>
  4. </div>
  5. )
  6. }
  7. function Hello(props) { // Hello 组件
  8. return ( <h1 className={ this.props.name }>{ props.children }</h1> )
  9. }

  1. import React from 'react' // App 组件
  2. class App extends React.Component {
  3. render() {
  4. return ( <div>
  5. <Hello name='frank'>你好</Hello>
  6. </div>
  7. )
  8. }
  9. }
  10. class Hello extends React.Component { // Hello 组件
  11. constructor(props){
  12. super(props)
  13. }
  14. render() {
  15. return ( <h1 className={ this.props.name }>{ this.props.children }</h1> )
  16. // this.props.children 为子组件或 text 的值
  17. }
  18. }

state (内部数据)

  • React 希望不要在旧的数据上更改,而是产生一个新数据替换(函数式理念)

    函数

    1. function App(props) {
    2. const [n, setN] = React.useState(0) // React.useState 返回一个数组,对参数 0 取赋值
    3. const onClick = () => setN(n + 1)
    4. return (<h1> n:{n}
    5. <button onClick={onClick}>+1</button>
    6. </h1>)
    7. }

  • 调用 setState 才会触发 UI 更新,并且是异步的,所以推荐使用 setState(函数)

    1. import React from 'react'
    2. class Hello extends React.Component {
    3. constructor(props) {
    4. super(props)
    5. this.state = {n: 0}
    6. // 等同于写在这里 this.add = () => { this.setState({n: this.state.n + 1}) }
    7. // 使用箭头函数,因为 this 不可变
    8. }
    9. add = () => { this.setState((state) => {n: state.n + 1}) }
    10. // 因为 setState 时异步的,使用函数获取实时的 state
    11. render() {
    12. return (<h1> n:{this.state.n}
    13. <button onClick={this.add}>+1</button>
    14. // button.onClick.call(null,event)
    15. </h1>)
    16. }
    17. }

    函数式更新

  • 如果新的 state 需要通过使用先前的 state 计算得出,那么可以将函数传递给 setState。该函数将接收先前的 state,并返回一个更新后的值。下面的计数器组件示例展示了 setState 的两种用法:

    1. function Counter({initialCount}) {
    2. const [count, setCount] = useState(initialCount);
    3. return (
    4. <>
    5. Count: {count}
    6. <button onClick={() => setCount(initialCount)}>Reset</button>
    7. <button onClick={() => setCount(prevCount => prevCount - 1)}>-</button> // 获取最新 state
    8. <button onClick={() => setCount(prevCount => prevCount + 1)}>+</button>
    9. </>
    10. );
    11. }
  • “+” 和 “-” 按钮采用函数式形式,因为被更新的 state 需要基于之前的 state。但是“重置”按钮则采用普通形式,因为它总是把 count 设置回初始值。

  • 如果你的更新函数返回值与当前 state 完全相同,则随后的重渲染会被完全跳过。

复杂 state

  • 使用 Object.assign 或者 ... 将 state 进行合并

    函数

  • 常规写法

    1. function Hello(props) {
    2. const [n,setN] = React.useState(0)
    3. const [m,setM] = React.useState(0)
    4. return ( <h1> n:{ n }
    5. <button onClick={ ()=>setN(n+1) }>+1</button>
    6. m:{ m }
    7. <button onClick={ ()=>setM(m+1) }>+1</button>
    8. </h1> )
    9. }
  • 函数组件的复杂 state,不会自动合并类,需要手动合并

    1. function App(props) {
    2. const [state, setState] = React.useState({n: 0, m: 0})
    3. return (<h1> n:{ state.n }
    4. <button onClick={() => setState({...state, n: state.n + 1})}>+1</button>
    5. m:{ state.m }
    6. <button onClick={() => setState({...state, m: state.m + 1})}>+1</button>
    7. </h1>)
    8. }

  • 类组件的复杂 state,会自动合并第一层

    1. import React from 'react'
    2. class Hello extends React.Component {
    3. constructor(props) {
    4. super(props)
    5. this.state = {
    6. n: 0,
    7. m: 0,
    8. user:{
    9. id:1,
    10. name:'frank'
    11. }
    12. }
    13. }
    14. change = () => {
    15. const user = {...this.state.user}
    16. user.name = 'jack'
    17. this.setState( {user} )
    18. }
    19. render() {
    20. return (<h1> id:{ this.state.user.id }
    21. name:{ this.state.user.name }
    22. <button onClick={ this.change }>change</button>
    23. </h1>)
    24. }
    25. }

    事件

    函数

    1. function Hello(props) {
    2. const [n,setN] = React.useState(0) // React.useState 返回一个数组,对参数 0 取赋值
    3. return ( <h1> n:{ n }
    4. <button onClick={ ()=>setN(n+1) }>+1</button>
    5. </h1> )
    6. }

  • 4 等同于 3 等同于 1+2 ```javascript class Hello extends React.Component { constructor(props) { super(props); this.state = {n: 0}; 1 this.add = this.add.bind(this); // 为了在回调中使用 this,这个绑定是必不可少的 3 this.add = ()=>{ this.setState({n: this.state.n + 1}) } // 更简洁的写法,箭头函数的 this 不会改变 }

2 add() { this.setState({n: this.state.n + 1}) } 4 add = () => { this.setState({n: this.state.n + 1}) } render() { return (

n:{this.state.n} // button.onClick.call(null,event)

) } } ```