一、this.setState()相关信息?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| constructor(props) { super(props); this.state = { num: 100, } }
componentDidMount() { this.setState({num: this.state.num+1}); console.log(this.state.num); this.setState({num: this.state.num+1},() => { console.log(this.state.num); });
this.setState({num: this.state.num+3}); this.setState({num: this.state.num+2}); this.setState({num: this.state.num+1});
this.setState(prevState => { return { num: prevState.num + 3, } }); this.setState(prevState => { return { num: prevState.num + 2, } }); this.setState(prevState => ({ num: prevState.num + 1 }));
this.setState({num: this.state.num + 1}); console.log(this.state.num); this.setState({num: this.state.num + 1}); console.log(this.state.num); setTimeout(() => { this.setState({num: this.state.num + 1}); console.log(this.state.num); this.setState({num: this.state.num + 1}); console.log(this.state.num); }, 0); }
|
二、手动进行事件绑定分别是什么,有啥区别?
(1)bind
方法: <button onClick={this.handleClick.bind(this, 'test')}>Test</button>
;
(2)构造器内声明: this.handleClick = this.handleClick.bind(this)
and
<button onClick={this.handleClick}>Test</button>
(3)箭头函数:<button onClick={() => this.handleClick()}>Test</button>
,自动绑定了定义此函数作用域的 this
。
思考:bind(this)
可能会导致重复绑定,尽量使用箭头函数绑定(性能优化的时候也可以提一提)。
三、Hook(16.8)
目标:不编写 class 的情况下使用 state 以及其他的 React 特性。
特点:
(1)无需修改组件结构的情况下复用状态逻辑。
(2)可将组件相互关联的部分拆分成更小的函数,复杂组件将变得容易理解。
(3)更简洁、更容易理解的代码。
1、状态钩子 State Hook useState
1 2 3 4 5 6 7 8
| const [name] = useState('name‘); const [count, setCount] = useState(0); const [arrs, setArrs] = useState(['text1’, ‘text2’]);
const fun1 = () => setCount(count + 1);
const fun2 = () => arrs.map(i => <li onClick={() => setArrs(f)}>{i}</li>) const fun3 = () => setArrs([...arrs, name]);
|
2、副作用钩子 Effect Hook useEffect
现在做的是事情对组件的状态和 UI 有影响。 订阅了数据有更改就更新。
1 2 3 4 5 6 7 8 9 10 11 12 13
| useEffect(() => { ... })
useEffect(() => { ... }, []) useEffect(() => { ... }, [count])
|
3、自定义钩子 Custom Hook
自定义hook
是一个函数,名称用“use
”开头,函数内部可以调用其他钩子。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| import React, {useState, useEffect} from 'react';
export default function Test() { function useValue(payload) { const [val, setValues] = useState('value'); useEffect(() => { setTimeout(() => { setValues('payload'); }) }) return val; }
const [count, setCount] = useState(0); const val = useValue('122'); return ( <div> {val ? val : ''} </div> ); }
|
4、 其他钩子
useContext
,useReduce
,useCallback
,useMemo
注:如果要进行数据优化,不更改就不渲染,可以使用useCallback
,useMemo
。
Context
组件跨层级通信 Context
相关 API
:
React.createContext
Context.Provider
Class.contextType
Context.Consumer
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| import React, {useState, useEffect, useContext} from 'react';
const myContext = React.createContext(); const { Provider, Consumer } = myContext;
function Child(props) { return ( <div> <p>{props.info}</p> <p>{props.age}</p> </div> ) }
// 使用方式二:使用hock function Child2(props) { const ctx = useContext(myContext); return ( <div> <p>Child2</p> <p>{ctx.age}</p> </div> ) }
class Child3 extends React.Component { static contextType = myContext; render() { return ( <div> <p>Child3</p> <p>{this.context.age}</p> </div> ) } }
export default function TestContext() { return ( <div> <Provider value={{info: 'name', age:123}}> <Consumer> {value => <Child {...value}/>} </Consumer> <Consumer> {value => <Child2 {...value}/>} </Consumer> <Consumer> {value => <Child3 {...value}/>} </Consumer> </Provider> </div> ); }
|