首页 > 解决方案 > 动态创建具有 onAction={} 属性的 JSX 元素,不更新状态(它们已损坏)

问题描述

考虑这两个setState变量,它们的值在承诺成功后发生变化(例如 ajax 调用)

const [ajax_response,getAjax_response] = useState("awaiting response"); //This one stores the ajax call response
const [showAjax,setShowAjax] = useState([]) //This one displays it

useEffect使用指定时调用的钩子做出承诺(在此示例中的第一个渲染中)

  useEffect(() => {
    fetchData().then(data => {
      //Here it stores the value in the first useState variable
      getAjax_response(data[0])

      //Here it loops throw the data and DYNAMICALLY CREATES some attributes based on the repsponse
      //In this example it just fetches a single number from the ajax call
      //And performs a loop until it reaches that (IRELEVANT)

      for (let i=0;i < data[0];i++) {
        let styled_data = <p onClick={() => console.log(ajax_response)}>{i}</p>;
        setShowAjax(prev => [...prev,styled_data])
      }
    })
  },[])

基本上会发生什么

问题 :

  return (
    <div className="App">
      <button onClick={() => console.log(ajax_response)}>THE NORMAL BUTTON</button> //Button set manually
      {showAjax} //The JSX elements set dynamically
    </div>
  );

THE NORMAL BUTTON得到正确console.log()答案ajax_response

但是 {showAjax}控制台中的动态创建按钮仅记录初始状态ajax_response

>>> awaiting response
  • 普通按钮
>>> CAT

TL:博士

使用 ONCLICK 属性动态生成的反应元素已损坏:它们不显示更新状态

标签: javascriptreactjsjsxes6-promise

解决方案


let styled_data = <p onClick={() => console.log(ajax_response)}>{i}</p>;
setShowAjax(prev => [...prev,styled_data])

问题是您将反应元素存储在状态中。这通常是一个坏主意,正是因为您在这里遇到的问题:它们永远不会重新渲染,因此很容易在渲染陈旧数据的地方创建错误。这里的函数<p>关闭了ajax_responseuseEffect 运行时存在的值。即,它在关闭时具有“等待响应”,并且始终如此。

相反,您的状态应该是创建组件所需的数据,然后您将在渲染时创建组件。

for (let i=0;i < data[0];i++) {
  // Modify this to store whatever data you need. 
  // Your example only used numbers, so i replicated that, but i expect your real code needs more.
  setShowAjax(prev => [...prev, i]); 
}

//...

return (
  <div className="App">
    <button onClick={() => console.log(ajax_response)}>THE NORMAL BUTTON</button>
    {showAjax.map(value => (
      <p onClick={() => console.log(ajax_response)}>{value}</p>
    )}
  </div>
);

推荐阅读