Компонент React не отображается после изменения состояния - PullRequest
0 голосов
/ 18 июня 2020

Как сказано в заголовке, когда мое состояние изменяется в моем компоненте, подкомпоненты не перерисовываются.

  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 строк, поэтому я вырезал и вставил только то, что, по моему мнению, было важным для проблемы, при необходимости могу предоставить больше

1 Ответ

2 голосов
/ 18 июня 2020

Я проверил этот код и, похоже, он работает нормально. Не могли бы вы указать, что установлено в компоненте 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 }));
}

Примечание: я переместил выборку в отдельную функцию, но это полностью зависит от вас.

Также обратите внимание, что я добавил url в состояние. Убедитесь, что ваши реквизиты настроены, чтобы избежать неожиданного поведения.

Edit 2: componentDidUpdate передаст вам prevProps и prevState в качестве параметров. С prevProps вы получаете доступ к всем реквизитам , которые вы получили в предыдущем обновлении, а с prevState, как вы можете догадаться, вы получаете доступ к независимо от вашего-состояния в предыдущем обновлении. И под «в предыдущем обновлении» я имею в виду до того, как обновление было выполнено.

...