我正在尝试使用输入字段的功能构建一个聊天应用程序,该功能可用作状态为 chat_groups 的chat_groups数组的过滤器。这是我的代码的样子:
constructor(props) {
super(props);
this.state = {
currUserId: "--id--",
chats: [],
chat_groups: [],
users: [],
};
}
.
.
.
<input
className="chat-group__search__input"
placeholder="Search for group..."
onChange={(ev) => {
console.log(ev.currentTarget.value);
var thatState = this.state;
thatState.chat_groups = thatState.chat_groups.map(
(gp) => {
gp["visible"] = gp.group_name
.toLowerCase()
.includes(ev.currentTarget.value);
return gp;
}
);
// getting correct state in thatState variable
this.setState(thatState);
}}
/>
// getting old state in setState callback and componentDidUpdate lifecycle
怪异的问题是在设置状态之前,我在thatState变量中获得了正确的值。但是在调用setState函数之后,如果我尝试在setState回调或componentDidUpdate生命周期中检查状态,那么我只会得到旧状态。
我也尝试了按键和更改事件。因此,似乎也不是一件大事。
我想知道代码中是否存在某些问题,或者可以采取一些措施来调试问题。
编辑:更改后,我当前的onChange如下所示,但问题仍然存在; setState函数似乎并没有改变状态,因为我只能在componentDidUpdate生命周期和setState回调中看到旧状态。
onChange={(ev) => {
console.log(ev.currentTarget.value);
let chat_groups = this.state.chat_groups.map((gp) => ({
...gp,
visible: gp.group_name
.toLowerCase()
.includes(ev.currentTarget.value),
}));
console.log(
"Before",
chat_groups.map((gp) => gp.visible)
);
this.setState({ chat_groups: chat_groups });
}}
答案 0 :(得分:1)
问题是您正在突变state
。
当您执行var thatState = this.state;
时,两个对象的引用仍然相同。因此,当您更新thatState.chat_groups
时,您也会自动更新/更改state
。
将您的onChange
方法更改为如下所示
onChange = ev => {
console.log(ev.currentTarget.value);
let { chat_groups } = this.state;
chat_groups = chat_groups.map(gp => ({
...gp,
visible: gp.group_name.toLowerCase().includes(ev.currentTarget.value)
}));
this.setState(state => ({
...state,
chat_groups
}));
};
//Other code
//....
//....
<input
className="chat-group__search__input"
placeholder="Search for group..."
onChange={this.onChange} />
我怀疑用输入值检查group_name
时存在一个问题,即您正在使用group_name
将lower case
转换为gp.group_name.toLowerCase()
,但输入值不是转换为lower case
。这可能是为什么visible
属性值未得到更新的一个问题。因此,在下面的代码段中,我在进行比较时也将输入值也转换为lower case
。
在这里,下面是您需要的可运行摘要。在console.log
的回调函数中执行setState
,状态正在更新。
class App extends React.Component {
constructor(props) {
super(props);
this.state = {
currUserId: "--id--",
chats: [],
chat_groups: [{
group_name: "Group One"
}, {
group_name: "Group Two"
}],
users: []
}
}
onChange = ev => {
console.log(ev.currentTarget.value);
let {
chat_groups
} = this.state;
chat_groups = chat_groups.map(gp => ({
...gp,
visible: gp.group_name.toLowerCase().includes(ev.currentTarget.value.toLowerCase())
}));
this.setState(state => ({
...state,
chat_groups
}), () => { console.log(this.state.chat_groups); });
};
render() {
return <input
placeholder="Search for group..."
onChange={this.onChange} />
}
}
ReactDOM.render(<App />, document.getElementById("react"));
.as-console-wrapper {
max-height: 100% !important;
}
<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>
<div id="react"></div>
答案 1 :(得分:0)
不,不要执行此操作for (File value : hidden) {
System.out.println(value);
}
,它只是一个对象,很容易发生变异,您将无法获得更新,因为从未发生过反应状态更改。
执行此操作var thatState = this.state
,然后进一步使用它并最后设置状态var { chat_groups } = this.state
,还尝试尽可能避免突变,这也意味着也复制this.setState({ chat_groups: chat_groups })
的值
答案 2 :(得分:0)
似乎您正在尝试直接操纵状态,这在React中是一个大问题。
onChange={(ev) => {
this.setState({
chat_groups: this.state.chat_groups.map((gp) => {
gp["visible"] = gp.group_name
.toLowerCase()
.includes(ev.currentTarget.value);
return gp;
})
});
}}
答案 3 :(得分:0)
状态只能使用setState
方法进行更新。
您直接在上面的代码-this isn't recommended中更改状态。您会得到意想不到的结果,而且这是不可预测的。
这就是您应该执行的操作-创建一个新的更新对象并将其传递给setState
。
onChange={(ev) => {
console.log(ev.currentTarget.value);
const updatedChatGroups = this.state.chat_groups.map((gp) => {
const visible = gp.group_name.toLowerCase().includes(ev.currentTarget.value);
return {
...gp,
visible,
};
});
// Update the modified object using this.setState().
this.setState({ chat_groups: updatedChatGroups });
}}