在路由更改时重置组件的内部状态
reset component's internal state on route change
我正在使用 react-router-v4 和 react 16。
我想在用户转到不同路线或返回同一路线时重置组件的内部状态。路由更改应该会破坏组件的内部状态,但它不会。而且我什至找不到在路由更改时通知组件的方法,因为它是嵌套组件而不是 Route
组件的直接呈现。请帮忙。
这是代码或 live codepen example --
const initialProductNames = {
names: [
{ "web applications": 1 },
{ "user interfaces": 0 },
{ "landing pages": 0 },
{ "corporate websites": 0 }
]
};
export class ProductNames extends React.Component {
state = {
...initialProductNames
};
animProductNames = () => {
const newArray = [...this.state.names];
let key = Object.keys(newArray[this.count])[0];
newArray[this.count][key] = 0;
setTimeout(() => {
let count = this.count + 1;
if (this.count + 1 === this.state.names.length) {
this.count = 0;
count = 0;
} else {
this.count++;
}
key = Object.keys(newArray[count])[0];
newArray[count][key] = 1;
this.setState({ names: newArray });
}, 300);
};
count = 0;
componentDidMount() {
this.interval = setInterval(() => {
this.animProductNames();
}, 2000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
componentWillReceiveProps(nextProps) {
console.log(nextProps.match);
if (this.props.match.path !== nextProps.match.path) {
this.setState({ ...initialProductNames });
this.count = 0;
}
}
render() {
return (
<section className="home_products">
<div className="product_names_container">
I design & build <br />
{this.createProductNames()}
</div>
</section>
);
}
createProductNames = () => {
return this.state.names.map(nameObj => {
const [name] = Object.keys(nameObj);
return (
<span
key={name}
style={{ opacity: nameObj[name] }}
className="product_names_anim">
{name}
</span>
);
});
};
}
您可以在路由更改上使用侦听器作为 上的示例,您可以在那里添加一个函数来更新主状态。
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.onRouteChanged();
}
}
onRouteChanged() {
console.log("ROUTE CHANGED");
}
我找到了解决方案。我没有退出理解为什么在重新安装时状态为 property initializer
不 reset/intialize。我认为它只初始化一次,而不是在每次路由更改时都初始化] -
我想知道如何在路由更改时重置组件的状态。但事实证明你不必这样做。每条路线呈现一个特定的组件。当路由更改时,所有其他组件都将被卸载,并且这些组件的所有状态也会被破坏。 但是请看我的代码。我使用 es7+ property initializer
来声明 state,count 。这就是为什么当组件在路由更改时重新安装时状态不再 resetting/initializing 的原因。
要修复它,我所做的就是将 state,initialProductNames,count;所有这些都变成 constructor
。现在它运行良好。
现在每次挂载和重新挂载时都是全新状态!!
问题不在于状态,而在于 initialProductNames。 属性 initializer 是一种糖语法,实际上它与创建构造函数并将代码移动到构造函数中是一样的。问题出在组件外部创建的initialProductNames,即整个系统只创建一次。
要为 ProductNames
的任何实例创建一个新的 initialProductNames
,请执行以下操作:
export class ProductNames extends React.Component {
initialProductNames = {
names: [
{ "web applications": 1 },
{ "user interfaces": 0 },
{ "landing pages": 0 },
{ "corporate websites": 0 }
]
};
state = {
...this.initialProductNames
};
// more code
componentWillReceiveProps(nextProps) {
console.log(nextProps.match);
if (this.props.match.path !== nextProps.match.path) {
this.setState({ ...this.initialProductNames });
this.count = 0;
}
}
这是一个示例,显示每次重新安装时总是重新创建 state
:https://codesandbox.io/s/o7kpy792pq
class Hash {
constructor() {
console.log("Hash#constructor");
}
}
class Child extends React.Component {
state = {
value: new Hash()
};
render() {
return "Any";
}
}
class App extends React.Component {
state = {
show: true
};
render() {
return (
<div className="App">
<button
type="button"
onClick={() =>
this.setState({
show: !this.state.show
})
}
>
Toggle
</button>
{this.state.show && <Child />}
</div>
);
}
}
我正在使用 react-router-v4 和 react 16。
我想在用户转到不同路线或返回同一路线时重置组件的内部状态。路由更改应该会破坏组件的内部状态,但它不会。而且我什至找不到在路由更改时通知组件的方法,因为它是嵌套组件而不是 Route
组件的直接呈现。请帮忙。
这是代码或 live codepen example --
const initialProductNames = {
names: [
{ "web applications": 1 },
{ "user interfaces": 0 },
{ "landing pages": 0 },
{ "corporate websites": 0 }
]
};
export class ProductNames extends React.Component {
state = {
...initialProductNames
};
animProductNames = () => {
const newArray = [...this.state.names];
let key = Object.keys(newArray[this.count])[0];
newArray[this.count][key] = 0;
setTimeout(() => {
let count = this.count + 1;
if (this.count + 1 === this.state.names.length) {
this.count = 0;
count = 0;
} else {
this.count++;
}
key = Object.keys(newArray[count])[0];
newArray[count][key] = 1;
this.setState({ names: newArray });
}, 300);
};
count = 0;
componentDidMount() {
this.interval = setInterval(() => {
this.animProductNames();
}, 2000);
}
componentWillUnmount() {
clearInterval(this.interval);
}
componentWillReceiveProps(nextProps) {
console.log(nextProps.match);
if (this.props.match.path !== nextProps.match.path) {
this.setState({ ...initialProductNames });
this.count = 0;
}
}
render() {
return (
<section className="home_products">
<div className="product_names_container">
I design & build <br />
{this.createProductNames()}
</div>
</section>
);
}
createProductNames = () => {
return this.state.names.map(nameObj => {
const [name] = Object.keys(nameObj);
return (
<span
key={name}
style={{ opacity: nameObj[name] }}
className="product_names_anim">
{name}
</span>
);
});
};
}
您可以在路由更改上使用侦听器作为
componentDidUpdate(prevProps) {
if (this.props.location !== prevProps.location) {
this.onRouteChanged();
}
}
onRouteChanged() {
console.log("ROUTE CHANGED");
}
我找到了解决方案。我没有退出理解为什么在重新安装时状态为 property initializer
不 reset/intialize。我认为它只初始化一次,而不是在每次路由更改时都初始化] -
我想知道如何在路由更改时重置组件的状态。但事实证明你不必这样做。每条路线呈现一个特定的组件。当路由更改时,所有其他组件都将被卸载,并且这些组件的所有状态也会被破坏。 但是请看我的代码。我使用 es7+ property initializer
来声明 state,count 。这就是为什么当组件在路由更改时重新安装时状态不再 resetting/initializing 的原因。
要修复它,我所做的就是将 state,initialProductNames,count;所有这些都变成 constructor
。现在它运行良好。
现在每次挂载和重新挂载时都是全新状态!!
问题不在于状态,而在于 initialProductNames。 属性 initializer 是一种糖语法,实际上它与创建构造函数并将代码移动到构造函数中是一样的。问题出在组件外部创建的initialProductNames,即整个系统只创建一次。
要为 ProductNames
的任何实例创建一个新的 initialProductNames
,请执行以下操作:
export class ProductNames extends React.Component {
initialProductNames = {
names: [
{ "web applications": 1 },
{ "user interfaces": 0 },
{ "landing pages": 0 },
{ "corporate websites": 0 }
]
};
state = {
...this.initialProductNames
};
// more code
componentWillReceiveProps(nextProps) {
console.log(nextProps.match);
if (this.props.match.path !== nextProps.match.path) {
this.setState({ ...this.initialProductNames });
this.count = 0;
}
}
这是一个示例,显示每次重新安装时总是重新创建 state
:https://codesandbox.io/s/o7kpy792pq
class Hash {
constructor() {
console.log("Hash#constructor");
}
}
class Child extends React.Component {
state = {
value: new Hash()
};
render() {
return "Any";
}
}
class App extends React.Component {
state = {
show: true
};
render() {
return (
<div className="App">
<button
type="button"
onClick={() =>
this.setState({
show: !this.state.show
})
}
>
Toggle
</button>
{this.state.show && <Child />}
</div>
);
}
}