state 和 setState的使用
State: 初始化数据值
在render函数里面解构state里面的初始值:例如 const { count } = this.state;
setState:用于更新数据
掌握 setState 的各种使用情况:
语法: setState(updater, [callback])
- updater: 更新数据 FUNCTION/OBJECT
- callback: 更新成功后的回调 FUNCTION
- 异步: react 通常会集齐一批需要更新的组件,然后一次性更新来保证渲染的性能
- 浅合并 Object.assign(),多层级数据手动合并
- 调用 setState 之后,会触发生命周期,重新渲染组件
//当页面有多个setState 时,react会集齐一批更新的组件,然后一次性更新来保证渲染的性能
class App extends Component {
state = {
count: 1,
nub: {
number: 5,
name: "React"
}
}
render() {
//获取state的里面的初始值
const { count, time, nub } = this.state;
return <div>
<p>count:{count}</p>
<button onClick={() => {
this.setState(()=>{
count: count + 1
},()=>{
//回调
console.log("组件更新完成");
});
}}>Count 递增</button>
<p>nub: {nub.number}</p>
//多层级数组合并
<button onClick={() => {
this.setState({
nub: {
...nub,
number: nub.number + 5,
}
})
}}>nub.number 递增</button>
</div>
}
}
export default App;
组件间通信
掌握 React 组件间通信:
组件间通信:
- 父组件向子组件传递信息:
- 父组件在调用子组件时,将要传递的信息加在子组件的属性中类似:name={nameVal}
- 子组件通过 props 属性接收父组件传递过来的信息,
父组件:
import { Component } from "react";
import List from "./list";
class App extends Component {
state = {
val:'内容',
}
render() {
const {val} = this.state;
return <div>
<List name={val}/>
</div>
}
}
export default App;
子组件:
import { Component } from "react";
class list extends Component {
render(){
//解构上级组件传递过来的值,或者方法
const { name} = this.props;
return<div>
<p>{name}</p>
</div>
}
}
export default list;
- 子组件向父组件传递信息:
- 在父组件上定义好相关的回调函数,将回调函数传递给子组件,
- 子组件调用父级的回调函数,向父级进行通信
父组件
import { Component } from "react";
import List from "./list";
class App extends Component {
state = {
openKey : "family",
val:'内容',
}
//定义回调函数
alterVal=(val)=>{
this.setState({
openKey: val
});
}
render() {
const {openKey, val,} = this.state;
return <div>
{ openKey}
<List name={val}
//将定义好的函数传递给子
alterVal={this.alterVal}/>
</div>
}
}
export default App;
子组件
import { Component } from "react";
class list extends Component {
render(){
//接收上级组件传递过来的数据及方法
const { name,alterVal } = this.props;
return<div>
<p>{name}</p>
<button onClick={()=>{
//使用回调函数改变数据
alterVal('修改了')
}}>子组件</button>
</div>
}
}
-
跨组件同信
-
中间组件层层传递 props
-
使用 context 对象
第一种方式:用中间组件的props传递数据,如果父组件的层级较深,那中间的每一层组件都要去传递props,增加了复杂度,这些props又不是每一层组件都需要的,当嵌套层级过深时,采用这种方式就需要斟酌了。
第二种方法:提供了一个无需为每层组件手动添加 props,就能在组件树间进行数据传递的方法。
Context 相当于一个全局变量,用Context 放入通信数据,在组件的任何层级都能获取到Context里面的通信数据,就不用了层层传递props了。1.在父组件调用 Provider 传递数据 2.在需要获取的子组件里面指定 contextType 读取当前Context 放入的通信数据
//context.js
import {createContext} from "react";
const context = createContext();
const {Provider,Consumer} = context;
export {Provider,Consumer};
export default context;
父组件:
//app.js
import {Provider} from "./context";//引入封装的Provider
//通信的数据和方法
state = {val:'内容', }
alterVal=(val)=>{
this.setState({
openKey: val
});
}
render(){
return<div>
<Provider
value={{
val:val,
alterVal:this.alterVal
}}>
<List/>
</Provider>
<div>
}
//list.js
render(){
return<Li/>
}
//Li1.js
//第一种方式用静态属性取context里面的值 static contextType = context;
import context from "./context";//获取存储的contextType
static contextType = context;
render(){
// const { name,alterVal } = this.props;
const { val,alterVal } = this.context;
console.log(val,)
return<div>
<p>{val}</p>
<button onClick={()=>{
alterVal('修改了3333')
}}>子组件</button>
</div>
}
//Li2.js
//第二种方式用Consumer包裹取值,回调函数里面的参数就是context里面的值
import { Consumer } from "./context";
render(){
return <Consumer>
{(context)=>{
console.log(context);
return <div>
<button onClick={()=>{
alterVal('修改了3333')
}}>子组件</button>
</div>
}}
</Consumer>}