当前位置: 首页 > 知识库问答 >
问题:

如何使用React hooks:setState()将道具同步到状态

宋俊艾
2023-03-14

我试图使用组件接收的道具,使用React hook setState()设置状态。我已尝试使用以下代码

import React,{useState , useEffect} from 'react';

const Persons = (props) =>  {

    // console.log(props.name);

   const [nameState , setNameState] = useState(props)

   console.log(nameState.name);
   console.log(props.name);

   return (
            <div>
                <p>My name is {props.name} and my age is {props.age}</p>
                <p>My profession is {props.profession}</p>
            </div>
        )

}

export default Persons;

问题是在加载组件时正在设置状态。但是当它收到新的道具时,状态并没有得到更新。在这种情况下,如何更新状态?提前谢谢。

共有3个答案

申屠健
2023-03-14

这一总体思路可以放在以下几个方面:

export function useStateFromProp(initialValue) {
  const [value, setValue] = useState(initialValue);

  useEffect(() => setValue(initialValue), [initialValue]);

  return [value, setValue];
}


function MyComponent({ value: initialValue }) {
  const [value, setValue] = useStateFromProp(initialValue);

  return (...);
}
荆亦
2023-03-14

useState(props)中的props值仅在初始渲染期间使用,使用settersetNameState进行进一步的状态更新。

此外,在更新派生状态时,不需要use效应

const Person = props => {
  const [nameState, setNameState] = useState(props.name);
  // update derived state conditionally without useEffect
  if (props.name !== nameState) setNameState(props.name);
  // ... other render code
};

从React文档:

[...]您可以在渲染期间更新状态权限。React将在退出第一次渲染后立即用更新的状态重新运行组件,这样就不会很贵。

[...] 渲染期间的更新正是getDerivedStateFromProps在概念上一直以来的样子。

本质上,我们可以通过摆脱额外的浏览器重新绘制阶段来优化性能,因为use效应总是在渲染提交到屏幕后运行。

这是一个人为的例子,演示了上述模式——在实际代码中,您可以阅读道具。直接命名。有关更合适的派生状态用例,请参阅React博客文章。

const Person = props => {
  const [nameState, setNameState] = React.useState(props.name);
  // Here, we update derived state without useEffect
  if (props.name !== nameState) setNameState(props.name);

  return (
    <p>
      <h3>Person</h3>
      <div>{nameState} (from derived state)</div>
      <div>{props.name} (from props)</div>
      <p>Note: Derived state is synchronized/contains same value as props.name</p>
    </p>
  );
};

const App = () => {
  const [personName, setPersonName] = React.useState("Lui");
  const changeName = () => setPersonName(personName === "Lukas" ? "Lui" : "Lukas");

  return (
    <div>
      <Person name={personName} />
      <button onClick={changeName}>Change props</button>
    </div>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.13.0/umd/react.production.min.js" integrity="sha256-32Gmw5rBDXyMjg/73FgpukoTZdMrxuYW7tj8adbN8z4=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.13.0/umd/react-dom.production.min.js" integrity="sha256-bjQ42ac3EN0GqK40pC9gGi/YixvKyZ24qMP/9HiGW7w=" crossorigin="anonymous"></script>
<div id="root"></div>
邓崇凛
2023-03-14

useState钩子函数参数只使用一次,而不是每次prop更改时都使用。您必须使用use效应钩子来实现您所称的组件WillReceiveProps/getDerivedStateFromProps功能

import React,{useState , useEffect} from 'react';

const Persons = (props) =>  {
   const [nameState , setNameState] = useState(props)

   useEffect(() => {
       setNameState(props);
   }, [props])

   return (
            <div>
                <p>My name is {props.name} and my age is {props.age}</p>
                <p>My profession is {props.profession}</p>
            </div>
        )

}

export default Persons;
 类似资料:
  • 问题内容: 我正在尝试使用组件接收的道具使用React hook setState()设置状态。我尝试使用以下代码: 问题是加载组件时正在设置状态。但是,当它收到新的道具时,状态不会更新。在这种情况下如何更新状态?提前致谢。 问题答案: hooks函数参数仅使用一次,而不是每次prop更改时使用。您必须使用钩子来实现所谓的功能

  • 我是新手,基本上我正在尝试立即更新父组件的状态及其子组件(和)道具。当前仅更新父组件的状态。我会一步一步地解释清楚。 这里我有一个父组件 这个组件有两个对象数组(和),分别作为道具发送到和组件。接收selectedPlayer和setSseltedPlayer。两个组件都有一个组件和一个选择输入。在组件中,用户将选择一个团队,他们将显示所选团队的球员,而在组件中,将选择一个球员,他们将显示选中的玩

  • 2)有没有另一种方法可以重写这个逻辑而不使用道具来设置状态? 父组件: 子组件

  • 我有一个组件,看起来像: 它从datepicker组件获取currentDate属性,如下所示: 当我从日期选择器中选择新日期时,this.props.current子组件上的日期会更新。这是我想要的日期。但是,当更新该prop时,它不会用新的预期数据重新呈现表。我意识到我必须更新子表的状态才能重新渲染。我试图通过设置当前日期:this.props.current日期来设置ftchData()方法

  • 我正在为一家德国公司评估Dart,将各种Java程序移植到Dart,并对结果进行比较和分析。在浏览器中,飞镖轻松获胜。对于服务器来说,软件性能似乎是一个严重的问题(请看我的这个问题),但这基本上得到了缓解。 现在我正在移植一些“简单”的命令行工具,我没想到会有任何严重的问题,但至少有一个问题。一些工具确实会发出HTTP请求来收集一些数据,独立的Dart虚拟机只以异步方式支持它们。纵观所有我能找到的

  • 我为appsync迁移了一个Flatter本地插件来放大。现在我想知道在appsync控制台中更新GraphQL之后,如何在我的Flatter项目的android部分生成代码。 最初我使用: