该应用应按特定输入过滤单词。我想在渲染组件时使用setState()
调用一个函数,并且从技术上讲它正在工作,但是控制台中有警告。
警告:无法在现有状态转换过程中(例如在
render
内进行更新)。渲染方法应该纯粹是props和state的函数。
我猜想这是因为我正在不应该在render函数中调用函数,但是我应该怎么做呢?
class UsersList extends React.Component {
constructor(props) {
super(props);
this.state = {
allUsers: ["Michał", "Ania", "Kasia", "Tomek", "Hubert", "Jan", "Martyna", "Rafał", "Bartłomiej"],
filteredUsers: [],
input: null
}
}
filter() {
if (this.state.input !== this.props.inputValue) {
const filtered = this.state.allUsers.filter(user => user.toLowerCase().includes(this.props.inputValue));
this.setState({
filteredUsers: filtered.map(user => <li key={user}>{user}</li>),
input: this.props.inputValue
})
}
return this.state.filteredUsers;
}
render() {
this.filter()
return (
<ul>
{this.state.filteredUsers}
</ul>
)
}
}
class App extends React.Component {
constructor() {
super();
this.state = {input: ""};
this.handleInput = this.handleInput.bind(this);
}
handleInput(e) {
this.setState({input: e.target.value})
}
render() {
return (
<div>
<input onChange={this.handleInput} type="search"/>
<UsersList inputValue={this.state.input} />
</div>
);
}
}
答案 0 :(得分:1)
这里的问题是由于在渲染过程中对组件的状态进行了更改所致。
您应该避免在组件render()
函数期间直接设置组件状态(在组件filter()
函数期间调用render()
时会发生这种情况。)
相反,请考虑仅根据需要(例如,当state
属性更改时)更新组件的inputValue
。建议更改state
值时更新prop
的方法是通过getDerivedStateFromProps()
组件生命周期挂钩。
这是一个示例,说明如何在组件中使用此挂钩:
class UsersList extends React.Component {
constructor(props) {
super(props);
this.state = {
allUsers: ["Michał", "Ania", "Kasia", "Tomek",
"Hubert", "Jan", "Martyna", "Rafał",
"Bartłomiej"],
filteredUsers: [],
input: null
}
}
/* Add this life cycle hook, it replaces filter(). Props are updated/incoming
props, state is current state of component instance */
static getDerivedStateFromProps(props, state) {
// The condition for prop changes that trigger an update
if(state.input !== props.inputValue) {
const filtered = state.allUsers.filter(user => user.toLowerCase().includes(props.inputValue));
/* Return the new state object seeing props triggered an update */
return {
allUsers: state.allUsers
filteredUsers: filtered.map(user => <li key={user}>{user}</li>),
input: props.inputValue
}
}
/* No update needed */
return null;
}
render() {
return (<ul>{this.state.filteredUsers}</ul>)
}
}
希望这会有所帮助
答案 1 :(得分:0)
错误即将来临,因为它可能在组件内部创建一个无限循环。由于render
方法在状态更新且您的函数this.filter
正在执行状态更新时都会执行。现在,随着状态的更新,您的render方法再次触发该函数。
做到这一点的最佳方法是在lifecycle methods
中或保持App
中的用途,并通过始终传递已过滤用户列表以使其显示来使UserList
成为愚蠢的组件。