简体   繁体   English

React不会在道具变更时重新渲染

[英]React doesn't re-render on props change

I am kinda new to react and to the webitself. 我有点反应和对自己动手了。

this is my render function 这是我的渲染功能

    render() {
    const {repositories} = this.props

    return (
        <div className='mt4 bt b--black-20 boardingbox scrollarea-content' style={{overflow: 'scroll', height: '100vh'}}>
            {
                repositories.map((repo, index) => {
                    console.log(repo.name)
                    return <Note name={repo.name} desc={repo.name} key={index} onClick={ this.handleClick.bind(this) }/>
                })
            }
        </div>
    )
}

The repositories is changing the way I want, but for some reason the its not get re-rendered. 存储库正在改变我想要的方式,但是由于某种原因,它没有被重新渲染。 I passing the repositiores property from the parent. 我从父级传递了repositiores属性。

The first time I render it (click to the search button, get a response from the server, and set the repo array), its working fine. 我第一次渲染它(单击搜索按钮,从服务器获得响应,并设置存储库数组),它的工作正常。 But at the 2nd search, when there is something in the array, its not working properly, and not re-render. 但是在第二次搜索中,当数组中有东西时,它不能正常工作,也不会重新渲染。

UPDATE: 更新:

The parent's render / onClick 父母的渲染/ onClick

render() {
    const {repositories} = this.state
    return (
      <div className='w-third navpanel br b--black-20'>
        <SearchBar onClick={this.onClick} onChange={this.onChange}/>
        <RepoList repositories={repositories}/>
      </div>

      //<NewNote />
      //<Tags />
      //<NoteList />
    );
}

onClick = (event) => {
    const {searchTerm} = this.state

    let endpoint = 'https://api.github.com/search/repositories?sort=stars&order=desc&q=' + searchTerm;
    fetch(endpoint)
        .then(blob => blob.json())
        .then(response => {
            if(response.items)
              this.setState({ repositories: response.items });
        })
}

UP-UPDATE: 更新:

Search Comp: 搜索比较:

constructor({onClick, onChange}) {
super()
this.onClick = onClick
this.onChange = onChange
this.state = {
  imageHover: false
}}

render() {
return (
  <div className='flex items-center justify-between bb b--black-20'>
    <div className='ma2 inputContainer w-100'>
      <input className='pa1 pl4 boardingbox w-100 input-reset ba b--black-20 br4 black-50 f6' placeholder='repos' type="text" onChange={this.onChange}/>
    </div>
    <div className='mr2'>
      <div className='boardingbox pointer contain grow'>
        <img src={(this.state.imageHover) ? NoteImageOnHover : NoteImage} alt=''
          onMouseOver={()=>this.setState({imageHover: true})}
          onMouseOut={()=>this.setState({imageHover: false})}
          onClick={this.onClick}/>
      </div>
    </div>
  </div>
)}

first responde 第一回应

second responde 第二回应者

The root cause most probably is due to error in function binding. 根本原因很可能是由于函数绑定中的错误。

In your SearchComponent you are using the "props" to create function bindings in the contructor . SearchComponent您正在使用“ props”在构造函数中创建函数绑定。 This can cause your SearchComponent to refer to wrong instance of the functions for onClick and onChange . 这可能导致SearchComponent引用onClickonChange函数的错误实例。 Would suggest referring to the official documentation for more details. 建议参考官方文档以获取更多详细信息。

you do not need to rebind the functions in your SearchComponent , you can just use the functions received in props . 您不需要重新绑定SearchComponent的功能,只需使用props收到的功能。

  <input className='pa1 pl4 boardingbox w-100 input-reset ba b--black-20 br4 black-50 f6' placeholder='repos' type="text" onChange={this.props.onChange}/>
  <!-- snipped other irrelevant code -->
    <img src={(this.state.imageHover) ? NoteImageOnHover : NoteImage} alt=''
      onMouseOver={()=>this.setState({imageHover: true})}
      onMouseOut={()=>this.setState({imageHover: false})}
      onClick={this.props.onClick}/>

Why could be happening to cause this behavior Remember, constructor is only called once the component instance is being constructed, once it has been created and remains alive, React lifecycles take over. 为什么会发生这种现象,请记住,构造函数仅在构造组件实例后才被调用,一旦它被创建并保持活动状态,React 生命周期就会被接管。

So, when you first render your screen, the component is created and since there is only 1 of everything, it kind of works. 因此,当您第一次渲染屏幕时,就创建了该组件,并且由于所有组件中只有1个,因此它可以正常工作。 When you run your first search: onChange/onClick callbacks modify the state of the parent component. 当您运行第一个搜索时:onChange / onClick回调会修改父组件的状态。 Which then calls render on the parent component. 然后调用父组件上的render

At this point, it is possible that your SearchComponent maybe holding on to the wrong instance of the call back methods, which would thus not set state on the parent and thus not force re-render. 此时,您的SearchComponent可能会保留错误的回调方法实例,从而不会在父对象上设置状态,因此不会强制重新呈现。

Additional Notes on your constructor 有关构造函数的其他说明

Normally you shouldn't refer to props in your constructor, but if you need to, then you need to have it in the format below. 通常,您不应该在构造函数中引用props ,但是如果需要,则需要使用以下格式。 Here are the relevant docs : 以下是相关文档

constructor(props) {
   super(props);
   // other logic
}

and I am really ashamed that I could screw up like this. 我为能这样搞砸感到非常really愧。 So basicly the problem was: 所以基本上问题是:

return <Note name={repo.name} desc={repo.name} key={index} onClick={ this.handleClick.bind(this) }/>

So I was as stupid to use INDEX as a KEY so I could not add again the same key to the array. 因此,我非常愚蠢地使用INDEX作为KEY,因此无法再次将相同的键添加到数组中。

Thanks anyway guys! 谢谢大家! :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM