示例是使用useState来保持点击计数器的简单功能组件。
逐步执行Stepper MUI组件,我想创建具有不同初始值的Example组件实例,例如在步骤0,初始值100,在步骤1,初始值111,在步骤2,初始值112。
尽管逐步传递了每种情况,尽管传递了不同的初始值,但示例功能组件仅将状态保持为第一个初始值,即100。
文件是/Components/Navigation/Stepper01a.js,StepContent中引用了示例组件,而HorizontalLinearStepper组件中引用了示例组件。总体代码是Material UI Stepper组件中的示例。我只是试图对其进行测试,以在每个步骤中创建具有不同初始值的其他功能组件的不同实例(在本例中为示例)。
示例组件:
function Example({ init }) {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = React.useState(init)
return (
<div>
<p>init {init} </p>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>Click me</button>
</div>
)
}
StepContent组件:
function StepContent({ step }) {
console.log("step", step)
switch (step) {
case 0:
return <Example init={100} />
case 1:
return <Example init={111} />
case 2:
return <Example init={112} />
default:
return "Unknown step"
}
}
HorizontalLinearStepper组件:
export default function HorizontalLinearStepper() {
...
<div>
<StepContent step={activeStep} />
</div>
...
}
请参见运行示例https://mj3x4pj49j.codesandbox.io/ 代码https://codesandbox.io/s/mj3x4pj49j
在步骤0上单击“下一步”时,期望将计数的初始值设置为111,但仍为100;在步骤1中单击“下一步”时,期望将计数的初始值设置为112,但仍为100。一旦在第0步将状态计数初始化为100,则在第1步和第2步使用相同的状态,即状态未隔离。
是否会由于某种原因违反钩子规则而发生此问题?
答案 0 :(得分:2)
在组件内部,您做的正确。初始化值取自props
-这是普遍做法。
但是请注意,useState()
仅将初始化值应用于初始渲染(对于基于类的组件,componentDidMount
或constructor
)。使用该组件的方式不是重新创建<Example
,而是对其进行更新。
因此,换句话说,您将获得不带componentDidUpdate
的基于类的组件:React更新了现有的<Example>
而不是重新创建它并且不再应用componentDidMount
(对于您而言,它不会使用初始值初始化useState
)。
我看到了不同的处理方式。
key
进行更新。哈克但工作方式:switch (step) {
case 0:
return <Example key="step-1" init={100} />
case 1:
return <Example key="step-2" init={111} />
case 2:
return <Example key="step-3" init={112} />
default:
return "Unknown step"
}
useEffect
用作componentDidUpdate
的钩子版本:useEffect(() => {
setCount(init);
}, [init]);
这是一个棘手的时刻,因为您正在计算点击次数。因此,仅setCount(init)
可能不是一个好方法,并且会破坏您的计算。因此,实际代码可能要复杂得多。我不确定在这里,因为不了解计数背后的逻辑。
count
推送到父组件),您无需在init
更新后进行任何更新。答案 1 :(得分:1)
您需要给React一个提示,即在不同的步骤中需要使用Example组件的不同实例。此提示可以这样完成:
function StepContent({ step }) {
console.log("step", step)
switch (step) {
case 0:
return <Example init={100} key={0} />
case 1:
return <Example init={111} key={1} />
case 2:
return <Example init={112} key={2}/>
default:
return "Unknown step"
}
}
原因是React在所有情况下都在虚拟dom中看到一个Example,根据它的算法,它认为它是相同的组件,但使用了不同的prop,因此他只是更改其状态而不重新初始化它。