use*_*636 4 reactjs react-hooks
示例是使用 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>
)
}
Run Code Online (Sandbox Code Playgroud)
步骤内容组件:
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"
}
}
Run Code Online (Sandbox Code Playgroud)
HorizontalLinearStepper 组件:
export default function HorizontalLinearStepper() {
...
<div>
<StepContent step={activeStep} />
</div>
...
}
Run Code Online (Sandbox Code Playgroud)
参见运行示例https://mj3x4pj49j.codesandbox.io/ 代码https://codesandbox.io/s/mj3x4pj49j
在第 0 步单击 Next 后,count 预计将设置为 111,但仍为 100,在第 1 步单击 Next 后,count 预计将设置为 init 值 112,但仍为 100。似乎一旦状态计数在第 0 步初始化为 100,在第 1 步和第 2 步中使用相同的状态,即状态不是孤立的。
这个问题是否是由于违反 Hooks 规则而导致的?
在组件内部,您做得对。初始值取自props- 这是常见的做法。
但是请注意,useState()仅在初始渲染(componentDidMount或 constructor 基于类的组件)上应用 init 值。您使用该组件的方式不是重新创建<Example而是更新它。
因此,换句话说,在相同的情况下,您将获得基于类的组件而没有componentDidUpdate:React 更新现有<Example>而不是重新创建它并且不再适用componentDidMount(对于您的情况,它不会useState使用初始值进行初始化)。
我看到了不同的处理方式。
key. hacky但工作方式: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"
}
Run Code Online (Sandbox Code Playgroud)
useEffect用作挂钩版本componentDidUpdate:useEffect(() => {
setCount(init);
}, [init]);
Run Code Online (Sandbox Code Playgroud)
这是一个棘手的时刻,因为您正在计算点击次数。因此,只是进行setCount(init)可能不是一个好举动,并且会破坏您的计算。所以实际的代码可能要复杂得多。我在这里不确定,因为不了解计数背后的逻辑。
count送到父组件),您将不需要在更新后更新任何内容init。你需要给 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"
}
}
Run Code Online (Sandbox Code Playgroud)
原因是 React 在所有情况下都在虚拟 dom 中看到一个 Example,并且根据它的算法,它认为它是相同的组件,但具有不同的 prop,所以他只是改变了它的状态而不是重新初始化它。
| 归档时间: |
|
| 查看次数: |
1348 次 |
| 最近记录: |