Javascript 通过带有挂钩的道具更新状态

Javascript 通过带有挂钩的道具更新状态,javascript,reactjs,react-hooks,Javascript,Reactjs,React Hooks,我试图通过提升某个组件的状态并将其作为道具传递到另一个组件并尝试更新它,从而在单击该组件时更新该组件的状态 这是App.js function App() { const [currentConfig, setCurrentConfig] = useState(0); const availableConfigs = [ { id: 1, name: "Config 1", number: 1, key: 1 }, { id: 2, name: &qu

我试图通过提升某个组件的状态并将其作为道具传递到另一个组件并尝试更新它,从而在单击该组件时更新该组件的状态

这是App.js

function App() {
  const [currentConfig, setCurrentConfig] = useState(0);
  const availableConfigs = [
    { id: 1, name: "Config 1", number: 1, key: 1 },
    { id: 2, name: "Config 2", number: 2, key: 2 },
    { id: 3, name: "Config 3", key: 3 },
    { id: 4, name: "Config 4", key: 4 },
    { id: 5, name: "Config 5", key: 5 },
    { id: 6, name: "Config 6", key: 6 },
    { id: 7, name: "Config 7", key: 7 },
  ];

  const [configs, setConfigs] = useState(availableConfigs);

  //function undoConfigAnimation(currentConfig) {}

  return (
    <div>
      <Tree
        configs={configs}
        animateConfigs={startConfigAnimation}
        setConfig={setCurrentConfig}
        currentConfig={currentConfig}
      />
      <NavBar />
    </div>
  );

  function startConfigAnimation(configClicked) {
    console.log(currentConfig);
    configs.forEach((config) => {
      if (configClicked !== config.name) {
        var elm = document.getElementById(config.name);
        elm.style.transform = "translate(-200px)";
        setTimeout(() => (elm.style.transform = "rotateZ(180deg)"), 1000);
      }
    });
  }
}

export default App;
函数应用程序(){
const[currentConfig,setCurrentConfig]=useState(0);
const availableconfigures=[
{id:1,名称:“配置1”,编号:1,键:1},
{id:2,名称:“Config 2”,编号:2,键:2},
{id:3,名称:“Config 3”,键:3},
{id:4,名称:“Config 4”,键:4},
{id:5,名称:“Config 5”,键:5},
{id:6,名称:“Config 6”,键:6},
{id:7,名称:“Config 7”,键:7},
];
const[configs,setConfigs]=useState(availableConfigs);
//函数undoConfigAnimation(currentConfig){}
返回(
);
功能启动组织(已单击配置){
console.log(currentConfig);
configs.forEach((配置)=>{
如果(configClicked!==config.name){
var elm=document.getElementById(config.name);
elm.style.transform=“translate(-200px)”;
setTimeout(()=>(elm.style.transform=“rotateZ(180度)”),1000;
}
});
}
}
导出默认应用程序;
这是组件

function Tree(props) {
  return (
    <div class="treeContainer">
      {props.configs.map((config) => {
        return (
          <div
            id={config.name}
            class="container1"
            onClick={() => {
              props.setConfig(config.name);

              props.animateConfigs(config.name);
              if (props.currentConfig !== config.name) {
                props.setConfig.bind(config.name);
              }
            }}
          >
            <Configs configNumber={config.number} configName={config.name} />
          </div>
        );
      })}
    </div>
  );
}
export default Tree;
功能树(道具){
返回(
{props.configs.map((config)=>{
返回(
{
props.setConfig(config.name);
props.animateConfigs(config.name);
if(props.currentConfig!==config.name){
props.setConfig.bind(config.name);
}
}}
>
);
})}
);
}
导出默认树;
当前,它确实会更新状态,但它只会将其更新为单击之前的状态,因此,如果currentConfig==0,则示例输出如下

单击配置1 currentConfig=0 单击配置2
currentConfig=“config 1”

由于设置状态是异步的,因此console.log将始终落后一个。这并不意味着状态没有更新,而只是没有显示在控制台中或功能中

因此,流程将是:

  • 你把零钱寄出去
  • 您可以调用
    startConfiguration
    ,但它仍然处于同步状态,因此
    currentConfig
    仍然是以前的值
  • 使用新值更新状态
  • 有两种方法可以解决此问题:

  • 使用useEffect: 收听带有useEffect的
    currentConfig
    ,如果配置更改,则触发动画
  • 您已经将新的/更新的配置传递给
    startConfiguration
    ,因此您可以使用它

  • 我应该在哪里调用useffect()?我的想法和传递它是一样的,但我需要它也是全局的,这样我就可以把它传递到另一个组件中,这个组件将处理一些不同的动画功能。
    React.useEffect(() => startConfigAnimation(currentConfig), [currentConfig])