Tuo*_*nen 90 html javascript reactjs
为什么在以下伪代码示例中,当Container更改foo.bar时,Child不会重新呈现?
Container {
handleEvent() {
this.props.foo.bar = 123
},
render() {
return <Child bar={this.props.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
Run Code Online (Sandbox Code Playgroud)
即使我forceUpdate()在修改Container中的值后调用,Child仍然显示旧值.
Fra*_*ard 69
因为如果父级的道具发生变化,孩子不会重新渲染,但如果其状态发生变化:)
你所展示的是:https: //facebook.github.io/react/tips/communicate-between-components.html
它会通过props将数据从父级传递给子级,但是那里没有重新构造逻辑.
您需要将某个状态设置为父级,然后在父级更改状态下重新呈现子级.这可能有所帮助. https://facebook.github.io/react/tips/expose-component-functions.html
pol*_*a-c 50
更新子项以使其属性“键”等于名称。每次更改键时,组件都会重新渲染。
Child {
render() {
return <div key={this.props.bar}>{this.props.bar}</div>
}
}
Run Code Online (Sandbox Code Playgroud)
小智 45
这是一个相当老的问题,但它是一个长期存在的问题,如果只有错误的答案和解决方法,它不会变得更好。子对象不更新的原因不是缺少键或缺少状态,原因是您不遵守不变性原则。
React 的目标是让应用程序更快、响应更快、更易于维护等等,但你必须遵循一些原则。React 节点仅在必要时才会重新渲染,即它们已更新。React 如何知道组件是否已更新?因为它的状态已经改变了。现在不要将其与 setState 挂钩混淆。状态是一个概念,每个组件都有其状态。状态是组件在给定时间点的外观或行为。如果您有一个静态组件,那么您始终只有一种状态,并且不必处理它。如果组件必须以某种方式改变,那么它的状态就会改变。
现在react非常具有描述性。组件的状态可以从一些变化的信息中导出,并且该信息可以存储在组件外部或内部。如果信息存储在内部,那么这是组件必须跟踪自身的一些信息,我们通常使用像 setState 这样的钩子来管理这些信息。如果此信息存储在我们的组件外部,那么它会存储在不同的组件内部,并且必须跟踪它及其状态。现在另一个组件可以通过 props 向我们传递他们的状态。
这意味着如果我们自己的托管状态发生变化或者通过 props 传入的信息发生变化,React 就会重新渲染。这是自然行为,您不必将 props 数据传输到您自己的状态中。现在非常重要的一点来了:React 如何知道信息何时发生了变化?简单:就是做个比较!每当你设置一些状态或给React一些它必须考虑的信息时,它会将新给定的信息与实际存储的信息进行比较,如果它们不相同,React将重新渲染该信息的所有依赖项。在这方面不一样意味着 javascript === 运算符。也许你已经明白了。让我们看看这个:
let a = 42;
let b = a;
console.log('is a the same as b?',a === b); // a and b are the same, right? --> true
a += 5; // now let's change a
console.log('is a still the same as b?',a === b); // --> falseRun Code Online (Sandbox Code Playgroud)
我们创建一个值的实例,然后创建另一个实例,将第一个实例的值分配给第二个实例,然后更改第一个实例。现在让我们看看对象的相同流程:
let a = { num: 42};
let b = a;
console.log('is a the same as b?',a === b); // a and b are the same, right? --> true
a.num += 5; // now let's change a
console.log('is a still the same as b?',a === b); // --> trueRun Code Online (Sandbox Code Playgroud)
this.props.foo.bar = 123
Run Code Online (Sandbox Code Playgroud)
实际上更新了内存中“this”所指向的值。React 根本无法通过比较对象引用来识别此类更改。您可以更改对象的内容一千次,并且引用将始终保持不变,并且反应不会重新渲染依赖组件。这就是为什么你必须将 React 中的所有变量视为不可变的。要进行可检测的更改,您需要不同的引用,并且只能通过新对象获得它。因此,您不必更改对象,而是必须将其复制到一个新对象,然后在将其移交给反应之前可以更改其中的一些值。看:
this.props.foo.bar = 123
Run Code Online (Sandbox Code Playgroud)
如果您遵循不变性,所有子节点都会使用新的 props 数据进行更新。
pet*_*hor 19
我有同样的问题。这是我的解决方案,我不确定这是否是个好习惯,如果不是,请告诉我:
state = {
value: this.props.value
};
componentDidUpdate(prevProps) {
if(prevProps.value !== this.props.value) {
this.setState({value: this.props.value});
}
}
Run Code Online (Sandbox Code Playgroud)
UPD:现在您可以使用React Hooks执行相同的操作:(仅当component是一个函数时)
const [value, setValue] = useState(propName);
// This will launch only if propName value has chaged.
useEffect(() => { setValue(propName) }, [propName]);
Run Code Online (Sandbox Code Playgroud)
tjr*_*226 15
确认,添加 Key 有效。我浏览了文档以尝试了解原因。
React 希望在创建子组件时高效。如果它与另一个子组件相同,则不会呈现新组件,这会使页面加载速度更快。
添加一个 Key 会强制 React 渲染一个新组件,从而重置该新组件的 State。
https://reactjs.org/docs/reconciliation.html#recursing-on-children
Nel*_*les 14
当从functions和创建 React 组件时useState。
const [drawerState, setDrawerState] = useState(false);
const toggleDrawer = () => {
// attempting to trigger re-render
setDrawerState(!drawerState);
};
Run Code Online (Sandbox Code Playgroud)
这确实不工作
<Drawer
drawerState={drawerState}
toggleDrawer={toggleDrawer}
/>
Run Code Online (Sandbox Code Playgroud)
这确实有效(添加密钥)
<Drawer
drawerState={drawerState}
key={drawerState}
toggleDrawer={toggleDrawer}
/>
Run Code Online (Sandbox Code Playgroud)
Suj*_*are 10
根据React哲学组件无法改变其道具.它们应该从父母那里收到,并且应该是不可改变的.只有父母可以改变其子女的道具.
状态与道具的好解释
另外,阅读这个帖子为什么我不能更新react.js中的道具?
你应该使用setState功能.
Container {
handleEvent= () => { // use arrow function
//this.props.foo.bar = 123
//You should use setState to set value like this:
this.setState({foo: {bar: 123}});
};
render() {
return <Child bar={this.state.foo.bar} />
}
Child {
render() {
return <div>{this.props.bar}</div>
}
}
}
Run Code Online (Sandbox Code Playgroud)
您的代码似乎无效.我无法测试此代码.
小智 6
我的案例涉及 props 对象上有多个属性,并且需要在更改其中任何一个属性时重新渲染 Child。上面提供的解决方案是有效的,但是为每个解决方案添加一把钥匙变得乏味且肮脏(想象一下有 15 个......)。如果有人遇到这个问题 - 您可能会发现对 props 对象进行字符串化很有用:
<Child
key={JSON.stringify(props)}
/>
Run Code Online (Sandbox Code Playgroud)
这样,props 上每个属性的每次更改都会触发子组件的重新渲染。
希望对某人有所帮助。
小智 6
在此代码片段中,我们多次渲染子组件并传递key。
如果我们使用setState方法更改检查。在我们更改其key之前,它不会反映在 Child 组件中。我们必须将其保存在子项的状态中,然后更改它以相应地渲染子项。
class Parent extends Component {
state = {
checked: true
}
render() {
return (
<div className="parent">
{
[1, 2, 3].map(
n => <div key={n}>
<Child isChecked={this.state.checked} />
</div>
)
}
</div>
);
}
}Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
120488 次 |
| 最近记录: |