Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript React-更改this.state onClick使用array.map()呈现_Javascript_Reactjs - Fatal编程技术网

Javascript React-更改this.state onClick使用array.map()呈现

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

我不熟悉React和JavaScript

我有一个菜单组件,它在单击时渲染动画,然后将应用重定向到另一条路径,即咖啡路径

我想将单击(选中)的值传递到函数
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) 
  }