【问题标题】:React component not rendering after state change状态更改后反应组件不渲染
【发布时间】:2020-10-07 23:57:08
【问题描述】:

正如标题所说,当我的组件中的状态发生变化时,子组件不会重新渲染。

  class App extends Component {
    constructor() {
      super()
      this.state = {
        url: ""
      }
      this.handleWorkerSelect = this.handleWorkerSelect.bind(this)
    }
    handleWorkerSelect(url) {
      this.setState({ url })
    }
    render() {
      return (
        <div className="App">
          <Workers className="workers" handleClick={this.handleWorkerSelect}/>
          <HermesWorker url={this.state.url}/>
        </div>
      )
    }
  }

  const Workers = (props) => {
    return (
      <div>
        <button onClick={() => props.handleClick("http://localhost:5000/api")}>Worker 1</button>
        <button onClick={() => props.handleClick("http://localhost:2000/api")}>Worker 2</button>
      </div>
    )
  }
  export default App

这里是 hermesworker.js

class HermesWorker extends Component {
    constructor() {
      super()
      this.state = {
        items: [],
        visited: [{name: "This Drive", path: "@back", root: ""}]
      }

      this.handleFolderClick = this.handleFolderClick.bind(this)
      this.handleFileClick = this.handleFileClick.bind(this)
    }
    componentDidMount() {
      if (this.props.url.length === 0) return
      fetch(this.props.url)
      .then(res => res.json())
      .then(items => this.setState({ items }))
    }
    render() {
      const folders = this.state.items.map((item) => {
        if (!item.isfile) {
          return <Card handleClick={this.handleFolderClick} root={item.root} path={item.path} isfile={item.isfile} name={item.name}     size={item.size}/>
        }
      })
      const files = this.state.items.map((item) => {
        if (item.isfile) {
          return <Card handleClick={this.handleFileClick} root={item.root} path={item.path} isfile={item.isfile} name={item.name} s    ize={item.size}/>
        }
      })
      const pathButtons = this.state.visited.map((item) => {
        return <PathButton handleClick={this.handleFolderClick} root={item.root} path={item.path} name={item.name}/>
      })
      return (
        <div>
          {pathButtons}
          <div className="flex-container">
            {folders}
            {files}
          </div>
        </div>
      )
    }
}

本质上问题是 HermesWorker 组件没有被重新渲染以使用新的 url 属性。我不确定为什么会发生这种情况,因为例如,在 hermesworker 中,它会渲染其他在状态更改期间会重新渲染的子组件。

感谢任何信息

编辑已更新以添加爱马仕工作人员,该文件超过 100 行,因此我剪切并仅粘贴了我认为对问题很重要的内容,如果需要可以提供更多

【问题讨论】:

    标签: node.js reactjs web web-component


    【解决方案1】:

    我测试了该代码,它似乎工作正常。您能提供 HermesWorker 组件中设置的内容吗?

    编辑:您需要在组件更新时使用setState 设置您的状态。为此,您可以查找componentDidUpdate,它将在每次更新时运行。这与componentDidMount 不同,后者(希望)将运行一次,然后组件可能会更新并重新渲染,但重新渲染它不被视为“挂载”。所以你可以试试这个:

    constructor(props) {
      super(props);
      this.state = {
        url: '',
        items: [],
        visited: [{name: "This Drive", path: "@back", root: ""}]
      }
      this.fetchData = this.fetchData.bind(this);
    }
    componentDidMount() {
      //Mount Once
    }
    
    componentDidUpdate(prevProps, prevState) {
    
      if (this.state.url !== this.props.url) {
        this.setState({url: this.props.url});
        // Url state has changed.
      }
      if(prevState.url !== this.state.url){
        //run your fetch
        this.fetchData();
      }
    }
    fetchData(){
      if (this.props.url.length === 0) return
      fetch(this.props.url)
      .then(res => res.json())
      .then(items => this.setState({ items }));
    }
    

    注意:我将 fetch 移到了它自己的函数中,但这完全取决于你。

    另请注意,我将 url 添加到状态。确保设置好道具以避免意外行为。

    编辑 2:componentDidUpdate 将把 prevPropsprevState 作为参数交给你。使用prevProps,您可以访问上一次更新中获得的任何道具,使用prevState,您可能猜到,您可以访问whatever-your-state-was 上一次更新。 “上一次更新”是指在更新执行之前。

    【讨论】:

    • 已更新,如果您需要查看更多代码,请告诉我。只是不想在帖子中塞满一堆不必要的功能和东西。
    • 仍在工作。哪一行应该使用该网址?仅在 componentDidMount 中?或者还有别的地方吗?
    • 再次更新以显示更多内容,所以我想我已经解决了这个问题,但我不知道如何解决它,每次重新渲染 HermesWorker 时,它都没有运行 componentDidMount 这将使更改生效无需使用刷新按钮刷新组件即可在屏幕上显示。那么如何让组件在重新渲染时呈现全新的状态呢?
    • 我更新了答案。检查一下并告诉我这是否解决了。
    猜你喜欢
    • 2017-03-24
    • 2022-07-08
    • 2019-04-03
    • 2021-06-20
    • 2022-07-12
    • 2021-01-27
    • 2023-03-22
    • 2020-05-04
    • 1970-01-01
    相关资源
    最近更新 更多