Javascript 单击时反应更新状态
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/37828867/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React update state on click
提问by agriboz
I have small component which lists data structure as shown below. What i want to do is when i click the update
button i want to increment vote
key, however, i didn't find a way to do it properly. Do i need to update the whole data
state? I have little confuse on it.
我有一个小组件,它列出了如下所示的数据结构。我想要做的是当我点击update
按钮时我想增加vote
键,但是,我没有找到正确的方法。我需要更新整个data
状态吗?我对此没有什么困惑。
let MOCKDATA = [
{
id: 1,
name: 'Test 1',
vote: 0
},
{
id: 2,
name: 'Test 2',
vote: 2
}];
LinkListPage.js
LinkListPage.js
import React from 'react';
// import LinksData from '../LinksData';
import Links from './Links';
// import update from 'react-addons-update';
//localStorage.setItem('linksData', JSON.stringify(LinksData));
let MOCKDATA = [
{
id: 1,
name: 'Test 1',
vote: 0
},
{
id: 2,
name: 'Test 2',
vote: 2
}];
class LinkListPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
data: MOCKDATA
};
this.update = this.update.bind(this);
}
componentDidMount() {
}
update() {
// this.setState({
// data:
// })
}
render() {
let list = this.state.data.map( links => {
return <Links key={links.id} update={this.update} data={links} />;
});
return (
<div>
<ul>{list}</ul>
{console.log(this.state.data)}
</div>
);
}
}
export default LinkListPage;
LinksPage.js
链接页面.js
import React, {PropTypes} from 'react';
const Links = (props) => {
return (
<li>
<p>{props.data.name}</p>
<p>{props.data.vote}</p>
<button onClick={props.update}>Up</button>
</li>
);
};
Links.propTypes = {
data: PropTypes.object,
name: PropTypes.string,
vote: PropTypes.number,
update: PropTypes.func
};
export default Links;
HomePage.js
主页.js
import React from 'react';
import LinkListPage from '../containers/LinkListPage';
const HomePage = () => {
return (
<div>
<LinkListPage />
</div>
);
};
export default HomePage;
After reading the answers my final result is as below which works fine. Thanks anyway.
阅读答案后,我的最终结果如下,效果很好。不管怎么说,还是要谢谢你。
LinksPage.js
链接页面.js
const Links = (props) => {
return (
<li>
<p>{props.data.name}</p>
<p>{props.data.vote}</p>
<button onClick={() => props.update(props.data.id)}>Up</button>
</li>
);
};
LinkListPage.js
LinkListPage.js
update(id) {
const findId = LinksData.filter(item => {
item.id === id ? item.vote++ : false;
});
const data = Object.assign(...findId, LinksData);
this.state.data.sort((a, b) => {
return b.vote - a.vote;
});
//localStorage.setItem('linksData', JSON.stringify(this.state.data));
this.setState({data});
}
采纳答案by Ross Khanas
In this case, I would add onClick
handler to LinksPage
component.
在这种情况下,我会onClick
向LinksPage
组件添加处理程序。
class Links extends React.Component {
constructor(props) {
super(props);
this.onClick = this.onClick.bind(this);
}
onClick(e) {
// here you know which component is that, so you can call parent method
this.props.update(this.props.data.id);
}
render() {
return (
<li>
<p>{this.props.data.name}</p>
<p>{this.props.data.vote}</p>
<button onClick={this.onClick}>Up</button>
</li>
);
}
};
And change your update
function:
并更改您的update
功能:
class LinkListPage extends React.Component {
constructor(props, context) {
super(props, context);
this.state = {
data: MOCKDATA
};
this.update = this.update.bind(this);
}
update(itemId) {
// TODO: find and update your item, you can do it since you have an 'id'
const data = [...];
this.setState({
data,
});
}
}
回答by Mike Tronic
//pass link id to update method in the LinkListPage component. ref point read this for handling the update for deep understanding https://www.sitepoint.com/immutability-javascript/
//将链接ID传递给LinkListPage组件中的更新方法。参考点阅读此内容以处理更新以深入理解https://www.sitepoint.com/immutability-javascript/
//use immutablejs or es6 in the update method cause state is immutable in react
// 在更新方法中使用 immutablejs 或 es6 导致状态在反应中是不可变的
update(id) {
//find and update your item, you can do it since you have an 'id'
//follow link: http://codereview.stackexchange.com/questions/43438/writing-a-function-to-add-or-modify-an-existing-object-inside-an-array
// this.setState({
// data:
// })
}
const Links = (props) => {
return (
<li>
<p>{props.data.name}</p>
<p>{props.data.vote}</p>
<button onClick={() => props.update(props.id)}>Up</button>
</li>
);
};
回答by Safwat Fathi
I would use a lifecycle hook for that as onClick event have side-effects on the component state.
我会为此使用生命周期挂钩,因为 onClick 事件对组件状态有副作用。
you may have a look at this example as i try to listen to every click on the canvas, for that i used componentDidUpdate() method.
你可以看看这个例子,因为我尝试聆听画布上的每一次点击,为此我使用了 componentDidUpdate() 方法。
class Canvas extends Component {
state = {
drawing: false,
x: 0,
y: 0,
};
componentDidUpdate() {
// this will log after every click on canvas
console.log(this.state.drawing, this.state.x, this.state.y);
}
mouseDownHandler = (e) => {
this.setState({
drawing: true,
x: e.clientX,
y: e.clientY,
});
};
render() {
return (
<div>
<canvas
onMouseDown={this.mouseDownHandler}
ref="canvas"
width={640}
height={425}
></canvas>
</div>
);
}
}
you can try this snippet and have a look if we changed the console.log() function you will find it will need two clicks to see correct coordination.
你可以试试这个片段,看看我们是否改变了 console.log() 函数,你会发现它需要点击两次才能看到正确的协调。
I hope it is clear :).
我希望它很清楚:)。