React中的props和state

简介: React中的props和state

1.props和state区别:

  • props和state都是用来存储数据的

setState方法

1.setState是同步的还是异步的?

默认情况下setState是异步的

2.为什么setState是异步的?

主要是为了优化性能

3.如何拿到更新之后的数据?

setState方法其实可以接收两个参数, 通过setState方法的第二个参数, 通过回调函数拿到

4.setState一定是异步的吗?

不一定: 在定时器中, 在原生事件中

class Home extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            age: 20, // 张三通过setState修改了age
            name: 'sjl', // 李四通过setState修改name
            gender: 'female' // 王五通过setState修改gender
        }
    }
    render(){
        console.log('渲染界面');
        return (
            <div>
                <p>{this.state.age}</p>
                {/*
                <button onClick={()=>{this.btnClick()}}>按钮</button>
                */}
                <button id={'btn'}>按钮</button>
            </div>
        )
    }
    componentDidMount() {
        const oBtn = document.getElementById('btn');
        oBtn.onclick = () => {
            this.setState({
                age: 666
            });
            console.log(this.state.age); // 666
        }
    }
 btnClick(){
 setTimeout(()=>{
            this.setState({
                age: 666
            });
            console.log(this.state.age); // 666
        }, 0);
    }
}
class App extends React.Component{
    render(){
        return (
            <div>
                <Home/>
            </div>
        )
    }
}
export default App;

setState方法深入

1.setState是同步的还是异步的?

默认情况下setState是异步的

constructor(props){
        super(props);
        this.state = {
            age: 18,
        }
    }
this.setState({
            age: 111
        }, ()=>{
            console.log('回到函数中', this.state.age);
        });
        this.setState({
            age: 222
        });
        this.setState({
            age: 333
        });
        console.log(this.state.age); // 18
  1. 为什么setState是异步的?
    主要是为了优化性能,防止多次渲染
  2. 如何拿到更新之后的数据?
    setState方法其实可以接收两个参数,通过setState方法的第二个参数, 通过回调函数拿到

this.setState({
            age: 111
        }, ()=>{
            console.log('回到函数中', this.state.age);//111
        });
        console.log(this.state.age); // 18
  1. setState一定是异步的吗? =>不一定: 在定时器中, 在原生事件中

setTimeout(()=>{
            this.setState({
                age: 666
            });
            console.log(this.state.age); // 666
        }, 0);

1.setState是如何给state赋值的? 通过Object.assign()

let oldObj = {name:'lnj', age:18};
        let newObj = {age: 666};
        let obj = Object.assign({}, oldObj, newObj);
        console.log(obj);
// {name:'lnj', age:666}

render(){
        return (
            <div>
                <p>{this.state.name}</p>
                <p>{this.state.age}</p>
                <button onClick={()=>{this.btnClick()}}>按钮</button>
            </div>
        )
    }
    btnClick(){
        this.setState({
            age: 666
        });
    }
}

State合并现象?

因为setState会收集一段时间内所有的修改再更新界面,所以就出现了State合并现象

class Home extends React.Component{
    constructor(props){
        super(props);
        this.state = {
            age: 0
        };
    }
    render(){
        return (
            <div>
                <p>{this.state.age}</p>
                <button onClick={()=>{this.btnClick()}}>按钮</button>
            </div>
        )
    }
    btnClick(){
/*
1.为什么最终的一个值是1, 不是3
因为setState默认是一个异步的方法, 默认会收集一段时间内所有的更新, 然后再统一更新,所以就导致了最终的一个值是1, 不是3
* */
        this.setState({
            age: this.state.age + 1
        });
        this.setState({
            age: this.state.age + 1
        });
        this.setState({
            age: this.state.age + 1
        });
        // console.log(this.state.age); // 0
    }
}

因为setState默认是一个异步的方法, 默认会收集一段时间内所有的更新, 然后再统一更新,所以就导致了最终的一个值是1, 不是3

其原理如下:

let oldObj = {age: 0};
let stateList = [
   {age: oldObj.age + 1},
   {age: oldObj.age + 1},
   {age: oldObj.age + 1},
  {age: 0 + 1},
    // {age: 0 + 1},
    // {age: 0 + 1},
    //{age: 1},
    //{age: 1},
   // {age: 1}
];

setstate方法是异步的,this.oldObject.age由于是统一收集处理故都为0,0+1=1

如何解决setState合并现象

1.傻办法——回调函数无限嵌套

this.setState({
            age: this.state.age + 1
        }, ()=>{
            this.setState({
                age: this.state.age + 1
            }, ()=>{
                this.setState({
                    age: this.state.age + 1
                });
            });
        });

2.新变量保存数据

//preState是上次返回的state
this.setState((preState, props)=>{
            return {age: preState.age + 1}
        })
        this.setState((preState, props)=>{
            return {age: preState.age + 1}
        })
        this.setState((preState, props)=>{
            return {age: preState.age + 1}
        })
    }

实现原理

let oldObj = {age: 0};
let stateList = [
    (preState)=>{return {age: preState.age + 1}},
    (preState)=>{return {age: preState.age + 1}},
    (preState)=>{return {age: preState.age + 1}},
];
stateList.forEach((fn)=>{
    // {age: 1}
    // {agg: 2}
    // {agg: 3}
    let newObj =  fn(oldObj);
    // {age: 0} {age: 1} / {age: 1}
    // {age: 1} {age: 2} / {age: 2}
    // {age: 2} {age: 3} / {age: 3}
    oldObj = Object.assign({}, oldObj, newObj);//这次的结果保存到下一个对象中
});
console.log(oldObj);


目录
相关文章
|
2月前
|
前端开发 JavaScript
学习react基础(3)_setState、state、jsx、使用ref的几种形式
本文探讨了React中this.setState和this.state的区别,以及React的核心概念,包括核心库的使用、JSX语法、类与函数组件的区别、事件处理和ref的使用。
68 3
学习react基础(3)_setState、state、jsx、使用ref的几种形式
|
2月前
|
前端开发 JavaScript
react学习(13)props
react学习(13)props
|
2月前
|
前端开发
学习react基础(2)_props、state和style的使用
本文介绍了React中组件间数据传递的方式,包括props和state的使用,以及如何在React组件中使用style样式。
33 0
|
1月前
|
前端开发 JavaScript 调度
React 组件状态(State)
10月更文挑战第8天
23 1
|
2月前
|
前端开发
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
本文介绍了在React项目中如何添加路径别名alias以简化模块引入路径,设置组件props的默认值,以及如何二次封装Ant Design的Modal组件。文章还提供了具体的代码示例,包括配置Webpack的alias、设置defaultProps以及封装Modal组件的步骤和方法。
68 1
React添加路径别名alias、接受props默认值、并二次封装antd中Modal组件与使用
|
1月前
|
前端开发 JavaScript CDN
React Props
10月更文挑战第8天
12 0
|
2月前
|
前端开发
react学习(15)函数式组件中使用props
react学习(15)函数式组件中使用props
|
2月前
|
前端开发
react学习(14)类式组件的构造器与props
react学习(14)类式组件的构造器与props
|
2月前
|
前端开发 JavaScript
React 中的 props 属性传递技巧
【9月更文挑战第6天】本文详细介绍了React中`props`的基本用法,包括传递基本数据类型、对象和数组。文章通过多个代码示例展示了如何正确使用`props`,并探讨了常见的问题及解决方法,如`props`不可变性、默认值设置及类型检查等。正确掌握这些技巧有助于提升编程效率,编写出更健壮的代码。
64 13
|
2月前
|
前端开发
React使用hooks遇到的坑_state中的某几个属性数据变成了空字符
本文讨论了在React使用hooks时遇到的一个问题:state中的某些属性数据变成了空字符。作者通过在修改函数中重新解构赋值来获取最新的state值,解决了因数据更新不及时导致的问题。
69 0