【问题标题】:is it bad to use props value on react hook?在反应钩子上使用道具值是不是很糟糕?
【发布时间】:2019-11-12 07:11:10
【问题描述】:

我是 react 钩子的新手,我只是在文档上看不到这个:

const MyComponent = ({myProp}) => {
 const [myPropHook, setPropHook] = useState(myProp)
...
}

我想知道这是否是一个好习惯?

【问题讨论】:

  • 在我看来,如果您希望仅将 myProp 用作初始值,这是可以的,否则我建议您使用 useRef(),以防您需要在 myProp 更改时更新本地状态.
  • 有一个合理的用例。例如,如果您有一个表单,并且 props 保存对象的服务器状态,您希望 state 保存用户当前输入的内容,并且 props 仅在服务器更新对象状态后更新。
  • @apokryfos 在该示例中,您应该使用道具,直到更新内部状态。
  • @WillJenkins 澄清一下。内部状态是例如服务器上的数据库行。道具保存行数据。组件状态将保存用户对该数据的修改,但在修改的数据到达服务器并且服务器更新行之前,不应更新道具。在这种情况下,不使用状态意味着您的表单输入将是只读的。这假设将有一个提交按钮来触发服务器更新,而不是一个按你类型更新类型的框

标签: javascript reactjs


【解决方案1】:

您传递给useState 的值用作状态变量的起始值。因此,当您的组件道具发生变化时,它们不会影响您正在使用的状态变量。初始值将是发送到组件的第一个道具,之后只能使用setPropHook 函数进行修改。

因此,简而言之,使用 props 作为 useState 的初始化程序绝对是一种代码味道,因为阅读代码并不能正确传达实际发生的情况。

【讨论】:

    【解决方案2】:

    你看不到太多,因为它对于 React 应用程序应该如何分配其状态没有多大意义。

    如果 prop 值设置在树的较高位置,则不应将其用作组件中单独状态的一部分。使用 prop 值间接确定组件的状态是有意义的,例如“如果 prop 是 this,则将 state 设置为 that”,但不要直接将 prop 复制到初始值价值。

    换句话说,组件的内部状态(通过useStateuseReducer Hooks 访问)应该由组件决定,而不是直接由父组件决定。

    【讨论】:

      【解决方案3】:

      是的,这很糟糕。您正在做的是将道具传递给状态,许多人不鼓励这样做。

      React 文档说“使用 props 生成状态通常会导致重复“真实数据源”,即真实数据在哪里。”。危险在于,如果在组件没有刷新的情况下更改了 props,则永远不会显示新的 prop 值,因为从 props 初始化 state 仅在组件首次创建时运行。

      唯一的例外是将道具用作内部控制状态的种子。经过几年的react开发,我从来没有遇到过这种情况。

      进一步阅读:
      React component initialize state from props(SO 问题)
      React Anti-Patterns: Props in Initial State(medium.com 文章)
      Why Setting Props as State in React.js is Blasphemy(博客文章)

      【讨论】:

        【解决方案4】:

        如果您尝试接收该功能组件的道具,那么可以,但与您编写的不完全一样。所以在父组件中你会有这样的东西:

        const App = () => {
          const [resource, setResource] = useState("posts");
        

        然后在 JSX 内部有一个组件,如下所示:

        const App = () => {
          const [resource, setResource] = useState("posts");
        
          return (
            <div>
              <div>
                <button onClick={() => setResource("posts")}>Posts</button>
                <button onClick={() => setResource("todos")}>Todos</button>
              </div>
              <ResourceList resource={resource} />
            </div>
          );
        };
        

        ResourceList 组件必须能够接收App 组件传递给它的道具。在基于类的组件中,你可以使用{this.props.resource},但在我们的例子中,它是一个使用 React 钩子的函数式组件,你想像这样编写它:

        const ResourceList = (props) => {
          const [resources, setResources] = useState([]);
        

        或者像这样通过 ES6 解构:

        const ResourceList = ({ resource }) => {
          const [resources, setResources] = useState([]);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-10-06
          • 2011-09-20
          • 2020-11-04
          • 2010-12-09
          • 2010-12-16
          • 2019-01-13
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多