React useState - useState 和数组的奇怪行为
React useState - strange behaviour with useState and arrays
使用下面的示例组件,将 'setter' 从 useState 传递到子项可以很好地处理字符串,但不适用于数组。它说 setter(仅对于数组)是 'not a function'。在父级中使用 setter 效果很好。通过在父级中调用方法来解决它也可以,但我不明白为什么需要这样做。
为什么会这样?
import React, { useState } from 'react';
function App() {
const [testString, setTestString] = useState('initial string value');
const [testSimpleArray, setTestSimpleArray] = useState(['one initial', 'two initial']);
const handleArrayChange = (arg) => {
setTestSimpleArray(arg);
}
return (
<>
<Subcomponent
testString={testString}
setTestString={setTestString}
testSimpleArray={testSimpleArray}
setSimpleArray={setTestSimpleArray}
altArrayChanger={handleArrayChange}
></Subcomponent>
<button onClick={() => setTestSimpleArray(['new from parent', 'new two from parent'])}>Set array in parent (works)</button>
</>
);
}
子组件
function Subcomponent({testString, setTestString, testSimpleArray, setTestSimpleArray, altArrayChanger}) {
return (
<>
<div>
<h2>String</h2>
{testString} <br />
<button onClick={() => setTestString('boo')}>setting string from subcomponent is ok</button>
<h2>Array</h2>
{JSON.stringify(testSimpleArray)} <br />
<button onClick={() => setTestSimpleArray(['new from subcomponent', 'new two from subcomponent'])}>Set array in subcomponent fails</button>
<button onClick={() => altArrayChanger(['new alt from subcomponent', 'new alt two from subcomponent'])}>Workaround (call parent event to do the update there)</button>
</div>
</>
);
}
export default App;
问题
Subcomponent
被定义为采用 setTestSimpleArray
prop
Subcomponent({
testString,
setTestString,
testSimpleArray,
setTestSimpleArray, // <--
altArrayChanger
})
而是传递了一个道具setSimpleArray
<Subcomponent
testString={testString}
setTestString={setTestString}
testSimpleArray={testSimpleArray}
setSimpleArray={setTestSimpleArray} // <--
altArrayChanger={handleArrayChange}
/>
解决方案
正确传递道具
<Subcomponent
testString={testString}
setTestString={setTestString}
testSimpleArray={testSimpleArray}
setTestSimpleArray={setTestSimpleArray} // <--
altArrayChanger={handleArrayChange}
/>
使用下面的示例组件,将 'setter' 从 useState 传递到子项可以很好地处理字符串,但不适用于数组。它说 setter(仅对于数组)是 'not a function'。在父级中使用 setter 效果很好。通过在父级中调用方法来解决它也可以,但我不明白为什么需要这样做。
为什么会这样?
import React, { useState } from 'react';
function App() {
const [testString, setTestString] = useState('initial string value');
const [testSimpleArray, setTestSimpleArray] = useState(['one initial', 'two initial']);
const handleArrayChange = (arg) => {
setTestSimpleArray(arg);
}
return (
<>
<Subcomponent
testString={testString}
setTestString={setTestString}
testSimpleArray={testSimpleArray}
setSimpleArray={setTestSimpleArray}
altArrayChanger={handleArrayChange}
></Subcomponent>
<button onClick={() => setTestSimpleArray(['new from parent', 'new two from parent'])}>Set array in parent (works)</button>
</>
);
}
子组件
function Subcomponent({testString, setTestString, testSimpleArray, setTestSimpleArray, altArrayChanger}) {
return (
<>
<div>
<h2>String</h2>
{testString} <br />
<button onClick={() => setTestString('boo')}>setting string from subcomponent is ok</button>
<h2>Array</h2>
{JSON.stringify(testSimpleArray)} <br />
<button onClick={() => setTestSimpleArray(['new from subcomponent', 'new two from subcomponent'])}>Set array in subcomponent fails</button>
<button onClick={() => altArrayChanger(['new alt from subcomponent', 'new alt two from subcomponent'])}>Workaround (call parent event to do the update there)</button>
</div>
</>
);
}
export default App;
问题
Subcomponent
被定义为采用 setTestSimpleArray
prop
Subcomponent({
testString,
setTestString,
testSimpleArray,
setTestSimpleArray, // <--
altArrayChanger
})
而是传递了一个道具setSimpleArray
<Subcomponent
testString={testString}
setTestString={setTestString}
testSimpleArray={testSimpleArray}
setSimpleArray={setTestSimpleArray} // <--
altArrayChanger={handleArrayChange}
/>
解决方案
正确传递道具
<Subcomponent
testString={testString}
setTestString={setTestString}
testSimpleArray={testSimpleArray}
setTestSimpleArray={setTestSimpleArray} // <--
altArrayChanger={handleArrayChange}
/>