【React学习笔记】组件间通信&生命周期

361 阅读3分钟

组件间通信

在 React.js 中,数据是从上自下流动(传递)的,也就是一个父组件可以把它的 state / props 通过 props 传递给它的子组件,但是子组件不能修改 props

React.js 是单向数据流!!!

1. 父传子:父级上直接定义,子级用props接收。
   如父级:<child data={data}></child>,在child组件中可用this.props.data访问。
2. 子传父:在父级上定义,子级进行回调。
   如父级上定义了函数fn(a),子级通过传递参数给该函数,父级中就能进行获取。
3. 其他组件之间:托管到共同的父亲
4. 扩展:context->跨组件通信->provider,consumer是配对的,一般用于第三方库中
   - 创建context
     React.createContext(defaultValue);
     { Consumer, Provider } = createContext(defaultValue)
   - 发数据
      Context.Provider 在父组件调用 Provider 传递数据,Provider包裹child组件
      value 要传递的数据
     如 :<Provider
      	    value={{
                count:count,
                add:this.add
              }}
        >
        <Child />
    	</Provider>
   - 接收数据
     -方法一:
       //class.contextType = Context;即将类下的contextType属性设为Context
       static contextType = Context;
       this.context;//value在this.context中
     - 方法二:
       //使用 Context.Consumer
            <Consumer>
                {(props)=>{
                    console.log(props);
                    return <div></div>
                }}
            </Consumer>

setState

setState(update[,callback]) 有以下几个注意点:

1. 浅合并(第一层) Object.assign
2. 如果想修改深层的一个参数,用...obj
   如state={name:'xiaobai',friend:{name:'xiaohei',age:20}},只想修改friend.name,需要用
   const {friend} = this.state;
   this.setState({friend:{...friend,age:30}})
3. 异步方法!!!
   为什么设计成异步?https://www.jianshu.com/p/cc12e9a8052c
   react通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能
4. update参数是 对象 或 函数
5. React中调用setState后会触发生命周期,重新渲染组件
6. 在react中不要直接state,而是在setState给它新值,否则在更新时获取不到更新前的state

生命周期

在getDerivedStateFromProps时是访问不到this的!!!(因为是静态方法)

总结上图:三个阶段

  • 挂载阶段mount(初始化组件到组件构建的视图真实地渲染到DOM中) constructor->实例化组件,一般就初始化props和state(state现在一般放到外面)

static getDerivedStateFromProps(props) -> 返回值是要关联进state的props

render -> 构建虚拟DOM

componentDidMount -> 检测组件挂载完成

  • 更新阶段update(setState组件开始更新,一直到组件完成真实的DOM更新) static getDerivedStateFromProps(props, state)->子组件中的props和state跟随父组件中的更新

shouldComponentUpdate() -> 判断是否更新,nextState、nextProps 【oldState->this.state、oldProps->this.props】;返回布尔值表示是否更新

render()

getSnapshotBeforeUpdate(prevProps, prevState) -> 获取快照(更新了state,但DOM还未更新时)

componentDidUpdate(prevProps,prevState,prevDOM) -> 处理副作用(请求),prevDOM时getSnapShotBeforeUpdate的返回值

  • 卸载阶段unMount(将组件从真实DOM中删除) componentWillUnmount->删除添加在全局的一些事件和信息

受控组件

受控组件和非受控组件

当想要获取表单的一些内部状态时,就可以将表单的内部状态和组件的状态进行绑定,这样就形成受控组件 受控组件: 让 表单控件 的内部状态 和我们 state 保持一致

非受控组件: 我们不需要同步 value 值(defaultValue,defaultChecked)

如果在普通组件上设置value就变成了受控组件,但若没设置onChange会报错,改为使用defalutValue !

简单例子:

class demo extends Component{
    state = {
    	val:""
    }
    
    changeVal = ({target})=>{
    	this.setState({val:target.value});
    }
    
    render(){
    	return <input placeholder="请输入你想输入的内容" value={this.state.val} onChange={this.changeVal}/>
    }
}