以下是将组件作为函数调用与将其渲染为元素的一些含义。
- 可能违反钩子规则
当你调用一个组件作为一个功能(见TestB()
下文),它包含挂钩的使用里面,在这种情况下的react认为钩内该功能属于父组件。现在,如果您有条件地渲染该组件 ( TestB()
),您将违反钩子规则之一。检查下面的示例,单击重新渲染按钮以查看错误:
错误:呈现的钩子比预期的少。这可能是由意外的提前退货声明引起的。
function TestB() {
let [B, setB] = React.useState(0);
return (
<div
onClick={() => {
setB(B + 1);
}}
>
counter B {B}
</div>
);
}
function App() {
let [A, setA] = React.useState(0);
return (
<div>
<button
onClick={() => {
setA(A + 1);
}}
>
re-render
</button>
{/* Conditionally render TestB() */}
{A % 2 == 0 ? TestB() : null}
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
现在您可以<TestB/>
改用并查看不同之处。
- 对帐可能无法按预期进行
当您将 react 组件渲染为 react 元素<TestB/>
,然后在下一次渲染时渲染一些不同的组件<TestC/>
而不是它(在组件层次结构中的同一位置),由于协调算法(并且由于组件类型已更改),react 将卸载<TestB/>
组件(它的所有状态都将消失)并安装一个新组件<TestC/>
。
但是,如果您将其称为函数(例如TestB()
),则组件类型 将不再参与协调,您可能无法获得预期的结果:
function TestB() {
return (
<div
>
<input/>
</div>
);
}
function TestC() {
console.log("TestC")
return (
<div
>
<input/>
</div>
);
}
function App() {
let [A, setA] = React.useState(0);
return (
<div>
<button
onClick={() => {
setA(A + 1);
}}
>
re-render
</button>
{/* Here we are alternating rendering of components */}
{A % 2 == 0 ? TestB() : TestC()}
</div>
);
}
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="react"></div>
- 在输入中输入一些东西
- 现在单击重新渲染按钮
- 您现在可以从日志中看到该组件
TestC
已呈现,但输入显示的值与您之前键入的值相同 - 当您呈现不同的组件时,这可能不是您想要的。发生这种情况是因为react协调算法无法检测到我们移动到了不同的组件(从TestB
到TestC
)并且没有从 DOM 中删除以前的输入实例。
现在将这些组件渲染为元素(<TestB/>
和<TestC/>
)以查看差异。