「React」很多人在滥用 state

简介: 群里有个朋友提问,上图是我们的部分对话过程。他希望将从路由传过来的参数 type 保存到组件的state中,然后在 render 中使用。于是,他就有了一个困扰,既然 type 要保存到 state 中,那我应该在哪个生命周期去获取它呢?很显然,这个小伙伴,自己给自己下了个套。在后续的沟通得知,他希望从 url 中,获取到传入的 type 类型,然后根据不同的 type ,渲染出来不同的组件。

我有很多机会看到别人写的代码。我发现,在使用 React 时,很多人都在滥用 state。


微信图片_20220511154615.png


群里有个朋友提问,上图是我们的部分对话过程。


他希望将从路由传过来的参数 type 保存到组件的state中,然后在 render 中使用。

于是,他就有了一个困扰,既然 type 要保存到 state 中,那我应该在哪个生命周期去获取它呢?


很显然,这个小伙伴,自己给自己下了个套。


在后续的沟通得知,他希望从 url 中,获取到传入的 type 类型,然后根据不同的 type ,渲染出来不同的组件。


我们仔细思考一下,这样场景之下的一个状态,type,适合放在 state 中吗?


在回答这个问题之前,我们来总结一下,React state 的特性。


在 React 哲学思维中,state 非常特别,当我们使用 setState 改变 state 中的属性时,会引起组件的重新渲染。


实际上,如果抛开 React,我们来看 state,无论是 class 组件,还是 hooks 组件,state 并无特别。


class A {
  state: {
    a: 1
  }
}


在对象 A 的内部,我们可以使用正常的操作方式,去修改它。


this.state.a = 2


而实际上,在 React 的官网中,特别明确的强调了,不要直接使用这样的方式去修改 state


微信图片_20220511154618.png


在 React 看来,state 有特殊的职能,它应该保存那些能够让组件重新渲染的状态。


那么也就意味着,在 React 的设计思维里,它并不希望你把任何状态都放在 state 中来管理。


结合上诉的案例分析,从路由传过来的参数 type,在当前组件中,并没有修改的必要。


当然接收到的 type 值会不一样,却不是在当前组件内部进行修改的。


那 type 在当前组件不修改,但是我要在很多地方使用到它,应该如何处理呢?

如下:


在 class 组件中


class A extends React.Component {
  type = this.props.navigation.getParams('type');
  render() {
    return (
      <div>
        {this.type === 0 && <SomeComponent1 />}
        {this.type === 1 && <SomeComponent2 />}
        {this.type === 2 && <SomeComponent3 />}
      </div>
    )
  }
}


在函数组件中


function A({navigation}) {
  const type = navigation.getParams('type');
  return (
    <div>
      {type === 0 && <SomeComponent1 />}
      {type === 1 && <SomeComponent2 />}
      {type === 2 && <SomeComponent3 />}
    </div>
  )
}


只有在组件内部有变化,并且变化会引起组件重新渲染的状态,我们才会把这些状态,使用 state 来管理。


正是由于没有正确悟透 state 的使用,导致在具体开发时,常常会产生非常多的疑问。

例如下面这个简单的案例大家可以思考一下。


非常多的人,在初学 React 时,都会这样使用,也有可能,你正在这样使用。


使用 state 来管理一个是否注册的状态 isRegister

注册成功之后,通过 setIsRegister 修改 isRegister 的状态为 true。修改之后,马上执行 dosomething 逻辑。


dosomething 中,为了逻辑更健壮,判断如果 isRegister 仍然为 false,则什么也不做。只有当 isRegister = true 时,才执行后续逻辑。


function Foo() {
  const [isRegister, setIsRegister] = useState(false)
  function dosomething() {
    // 如果没注册,什么逻辑也不执行
    if (!isRegister) {
      return;
    }
    // todo
    history.go('xxxxxx/a/b/c');
    // 。。。
  }
  function register() {
    api.register().then(() => {
      // 注册成功,执行函数 A,在A 中,使用 isRegistor 判断了逻辑
      setIsRegister(true)
      dosomething()
    })
  }
  return (
    <button onClick={register}>注册</button>
  )
}


我的问题是:


这样写,dosomething 中的后续逻辑能正常执行吗?


使用 state 管理 isRegister 合理吗?


如果不应该使用 state 管理 isRegister,那应该怎么办?


留给大家思考,相信大家都能找到答案。

相关文章
|
3月前
|
前端开发 JavaScript
学习react基础(3)_setState、state、jsx、使用ref的几种形式
本文探讨了React中this.setState和this.state的区别,以及React的核心概念,包括核心库的使用、JSX语法、类与函数组件的区别、事件处理和ref的使用。
76 3
学习react基础(3)_setState、state、jsx、使用ref的几种形式
|
3月前
|
前端开发
学习react基础(2)_props、state和style的使用
本文介绍了React中组件间数据传递的方式,包括props和state的使用,以及如何在React组件中使用style样式。
35 0
|
2月前
|
前端开发 JavaScript 调度
React 组件状态(State)
10月更文挑战第8天
33 1
|
7月前
|
存储 前端开发 API
第六章 react组件实例中三大属性之State
第六章 react组件实例中三大属性之State
|
4月前
|
前端开发
React组件实例更改state状态值(四)
【8月更文挑战第14天】React组件实例更改state状态值(四)
48 1
React组件实例更改state状态值(四)
|
4月前
|
前端开发 JavaScript
React组件实例state(三)
【8月更文挑战第14天】React组件实例state(三)
31 1
React组件实例state(三)
|
3月前
|
前端开发
React使用hooks遇到的坑_state中的某几个属性数据变成了空字符
本文讨论了在React使用hooks时遇到的一个问题:state中的某些属性数据变成了空字符。作者通过在修改函数中重新解构赋值来获取最新的state值,解决了因数据更新不及时导致的问题。
85 0
|
4月前
|
存储 前端开发
React 中的 state 和 props 有什么区别?
【8月更文挑战第31天】
53 0
|
5月前
|
存储 前端开发 JavaScript
前端框架与库 - React基础:组件、Props、State
【7月更文挑战第12天】React是JavaScript库,专注UI构建,基于组件化。组件是UI模块,可函数式或类定义。Props是组件间安全传递数据的只读参数,用defaultProps和propTypes保证正确性。State则是组件内部可变数据,用于驱动更新。使用setState()确保正确变更和渲染。了解并妥善处理这些概念是高效React开发的基础。
74 7
|
6月前
|
存储 前端开发 JavaScript
React中有效地使用props和state来管理组件的数据和行为
React中有效地使用props和state来管理组件的数据和行为