Javascript React-更改this.state onClick使用array.map()呈现
我不熟悉React和JavaScript 我有一个菜单组件,它在单击时渲染动画,然后将应用重定向到另一条路径,即咖啡路径 我想将单击(选中)的值传递到函数Javascript React-更改this.state onClick使用array.map()呈现,javascript,reactjs,Javascript,Reactjs,我不熟悉React和JavaScript 我有一个菜单组件,它在单击时渲染动画,然后将应用重定向到另一条路径,即咖啡路径 我想将单击(选中)的值传递到函数this.gotoCoffee并更新this.state.select,但我不知道如何进行,因为我正在同一onClick事件中映射this.state.coffee中的所有项目 如何执行此操作并更新this.state。选择到单击的值 我的代码: class Menus extends Component{ constructor (pro
this.gotoCoffee
并更新this.state.select
,但我不知道如何进行,因为我正在同一onClick
事件中映射this.state.coffee
中的所有项目
如何执行此操作并更新this.state。选择到单击的值
我的代码:
class Menus extends Component{
constructor (props) {
super(props);
this.state = {
coffees:[],
select: '',
isLoading: false,
redirect: false
};
};
gotoCoffee = () => {
this.setState({isLoading:true})
setTimeout(()=>{
this.setState({isLoading:false,redirect:true})
},5000)
}
renderCoffee = () => {
if (this.state.redirect) {
return (<Redirect to={`/coffee/${this.state.select}`} />)
}
}
render(){
const data = this.state.coffees;
return (
<div>
<h1 className="title is-1"><font color="#C86428">Menu</font></h1>
<hr/><br/>
{data.map(c =>
<span key={c}>
<div>
{this.state.isLoading && <Brewing />}
{this.renderCoffee()}
<div onClick={() => this.gotoCoffee()}
<strong><font color="#C86428">{c}</font></strong></div>
</div>
</span>)
}
</div>
);
}
}
export default withRouter(Menus);
像这样的人:
<div onClick={(c) => this.gotoCoffee(c)}
this.gotoCoffee(c)}
大约:
<div onClick={(event => this.gotoCoffee(event.target.value}
this.gotoCoffee(event.target.value}
但是console.log(this.state.select)
为两次尝试显示了“未定义的”
”
似乎我正在用“c”传递类
浏览器在重定向时的uri上精确显示:
http://localhost/coffee/[对象%20对象]
现在,如果我将映射的“c”传递给{this.renderOffee(c)}
,这不是一个onClick
事件,那么我将设法传递数组项
但我需要传递的不是对象,而是单击的值“c”到this.gotoCoffee(c)
,然后更新this.state。选择
如何修复此问题?因此,根据您的代码,您可以采用几种方法来解决此问题
onClick=(event)=>this.gotoCoffee(event.target.value)
这看起来像是您想要的方法
onClick=()=>this.gotoCoffee(c)
c
将与数组中的项目相关。您可以在render
中将元素的index
传递给gotoCoffee
,并在gotoCoffee
中使用闭包。然后在gotoCoffee
中,以this.state.coffee[index]
的形式访问该元素
gotoCoffee = (index) => {
this.setState({isLoading:true, select: this.state.coffees[index]})
setTimeout(()=>{
this.setState({isLoading:false,redirect:true})
},5000)
}
render(){
const data = this.state.coffees;
return (
<div>
<h1 className="title is-1"><font color="#C86428">Menu</font></h1>
<hr/><br/>
{data.map((c, index) =>
<span key={c}>
<div>
{this.state.isLoading && <Brewing />}
{this.renderCoffee()}
<div onClick={() => this.gotoCoffee(index)}
<strong><font color="#C86428">{c}</font></strong></div>
</div>
</span>)
}
</div>
);
}
}
gotoCoffee=(索引)=>{
this.setState({isLoading:true,select:this.state.coffes[index]})
设置超时(()=>{
this.setState({isLoading:false,redirect:true})
},5000)
}
render(){
const data=this.state.coffee;
返回(
菜单
{data.map((c,index)=>
{this.state.isLoading&&}
{this.renderOffee()}
this.gotoCoffee(索引)}
{c}
)
}
);
}
}
所有的答案看起来都很好,对您很有用,很明显,您没有在click handler中传递正确的值,这是一个错误。但由于您是这个时代的新手,我认为最好以这种方式更改您的实现:
- 根本不需要使用构造函数,您可以使用初始值声明状态属性:
class Menus extends Component{
state= {
/* state properties */
};
}
- 当您在render方法中声明函数时,每次渲染都会创建一个新的函数,该函数具有一定的成本且未进行优化。最好使用currying:
handleClick = selected => () => { /* handle click */ }
render () {
// ...
coffees.map( coffee =>
// ...
<div onClick={ this.handleClick(coffee) }>
// ...
}
由于重定向
替换了路由,我认为您希望正常的页面更改而不是替换,因此我建议使用历史记录。推送
。您的问题几乎已经解决了。我敢打赌,您的状态未定义的原因是由于事件
设置状态
是异步的操作,并不总是立即发生。通过直接关闭事件并允许功能正常进行,在可以设置状态之前释放事件。我的建议是将您的gotoCoffee
功能更新为:
gotoCoffee = (e) => {
const selectedCoffee = e.target.value
this.setState({isLoading:true,select:selectedCoffee},() =>
{console.log(this.state.select})
setTimeout(()=>{
this.setState({isLoading:false,redirect:true})
},5000)
}
请注意,我已将您的console.log行移动到setState中的回调函数,以便在状态更新之前不会触发该回调函数。每当您使用类组件并且需要在更新状态后立即执行某些操作时,请使用回调函数。看起来您可以将c
作为参数传递给this.gotoCoffee()
,除非我遗漏了什么?谢谢,但是你能在你的答案中添加this.setState({select:c})
,或者它是如何实现的吗?谢谢你的回答。实际上我需要构造函数。这不是完整的组件代码。我需要在其他地方使用this.props
。+1获取history.replace()的提示尽管如此,
。将考虑使用它而不是
@data\u garden很高兴听到它的帮助。如果可能,尝试使用componentDidMount
我猜您的状态声明有点问题状态:{
,作为类属性,它应该类似于状态={
。谢谢你的回答。我投赞成票。@AmerllicA你是对的。除非你有错误检查或鹰眼,否则这些错误是不明显的;)
handleClick = selected => () =>
this.setState(
{ isLoading: true},
() => setTimeout(
() => {
const { history } = this.props;
this.setState({ isLoading: false });
history.replace(`/${coffee}`);
}
, 5000)
);
gotoCoffee = (e) => {
const selectedCoffee = e.target.value
this.setState({isLoading:true,select:selectedCoffee},() =>
{console.log(this.state.select})
setTimeout(()=>{
this.setState({isLoading:false,redirect:true})
},5000)
}