我有状态结构,一开始就是这样:
messages:[
{id: 1, name: 'name1'},
{id: 2, name: 'name2'}, ...
]
我想要的是根据其id
键更新一条消息。我正在从服务器获取另一个这样的对象:
{id: 2, name: 'newName2'}
状态是一个数组:(2) [{…}, {…}]
。我不知道哪个索引的元素将被更新,我只知道对象内部的id键。
如何根据状态的键值更新状态内的对象?
答案 0 :(得分:2)
您可以使用findIndex
来获取要更新的对象的索引,并将其替换为新数组中的新对象,并将其设置为组件状态。
示例
class App extends React.Component {
state = {
messages: [{ id: 1, name: "name1" }, { id: 2, name: "name2" }]
};
updateMessage(newMessage) {
this.setState(prevState => {
const messages = [...prevState.messages];
const index = messages.findIndex(m => m.id === newMessage.id);
messages[index] = newMessage;
return { messages };
});
}
render() {
return (
<div>
{this.state.messages.map(message => (
<div key={message.id}>{message.name}</div>
))}
<button onClick={() => this.updateMessage({ id: 2, name: "newName2" })}>
Update message
</button>
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
<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="root"></div>
答案 1 :(得分:2)
如果需要通过键查找它们,最好将它们存储为{key:'value'}
对。
您有一些选择。
let id = 1
let message = messages [id -1];
message.foo = 'bar';
let prop = 'name', key = 'name1'
for (const message of messages) if (message[prop] === key) message.foo = 'bar'
const byProp = (prop,key) => ({[prop]:k}) => k == key
const message = messages.find (byProp('name', 'name1'))
const byProp = (arr,prop) => arr.reduce ((obj, itm) => ({...obj, [itm[prop]]:itm}),{})
let message = byProp (messages, 'name')['name1']
答案 2 :(得分:1)
这应该有效
const newMsg = { id: 10, message: 'hi' }
this.setState(({ messages } => {
return {
...messages.filter(x => x.id !== newMsg.id),
newMsg
}
};
答案 3 :(得分:1)
使用Array.map
修改数组
const messages = [
{id: 1, name: 'name1'},
{id: 2, name: 'name2'},
]
const updateById = obj => {
const { id } = obj;
// here we check if new object has the same id as the old one
// we replace old one with new
return messages.map(message => message.id === id ? obj : message)
}
console.log(
updateById({id: 1, name: 'newName'})
)
答案 4 :(得分:1)
有很多方法可以做到这一点。其中之一如下所示。
let x = [{id: 1, a: 1},{id: 2, b: 2}]
let newO = {id: 2, b: 3}
let y =[
...x.map(item => {
if (item.id === newO.id) {
return newO;
} else return item
})
]
console.log(y)
答案 5 :(得分:1)
这里是codesandbox,显示了下面的代码。
假设您像这样存储state
:
state = {
messages: [
{ id: 1, name: 'name1' },
{ id: 2, name: 'name2' },
{ id: 3, name: 'name3' }
]
}
然后,您可以使用findIndex()
根据ID查找消息,但是您还想确保不可变地更新状态。因此,您可以执行以下操作:
changeMessage = (id, newName) => {
// Search messages for a message with the given id, and return index
// of the matching message in array, or -1 if not found.
const arrayIndex = this.state.messages.findIndex((message) => (message.id === id))
if (arrayIndex === -1) {
console.log('No message found for id ' + id)
return
}
// Copy over the messages from state to an array that
// you can manipulate without affecting this.state.messages
let updatedMessages = [...this.state.messages]
// Update the message located by index
updatedMessages[arrayIndex] = {
id,
name: newName
}
this.setState({
messages: updatedMessages
})
}
}