Доступ к JSON из папки publi c в ReactApp - PullRequest
0 голосов
/ 09 мая 2020

У меня есть файл JSON, содержимое которого я хотел бы использовать в своем приложении React.

Это отрывок из моего кода

export default class App extends Component{
constructor(props){
    super(props);
    this.state = {
        entry : []
    }
}

componentDidMount(){
    fetch(process.env.PUBLIC_URL + `./js/data.json`)
    .then(res => res.json())
     .then(json => this.setState({ entry: json }));
}

render(){
    return(
        <div>
            <ul>
                {this.state.entry.map( x => (
                    <li>
                        <div className='centering'>
                            <span>
                                <img alt='' key={x.img} src={process.env.PUBLIC_URL + `./img/${x.img}.jpg`}/>
                            </span>
                            <span className='txt'>
                                { x.date }
                            </span>
                            <span>
                                <p>{ x.ctx }</p>
                            </span>
                        </div>
                        <div className='hr-line'></div>
                    </li>
                ))}
            </ul>
        </div>
    )
}

}

это содержимое моих данных. json

{
"entry" : {
    "2" : [
        {
            "date":"1/1/1",
            "img":"profile",
            "ctx":"as"
        }

    ],
    "1" : [
        {
            "date":"1/1/1",
            "img":"profile",
            "ctx":"as"
        }

    ]
}

Когда я сохраняю файл, в браузере отображается TypeError: this.state is null на render {this.state.entry.map (x => ...

Это там чего-то не хватает, или это невозможно сделать?

Заранее спасибо.

Ответы [ 2 ]

0 голосов
/ 09 мая 2020

Отрисовка выполняется до componentDidmount. Вам нужно дождаться загрузки ваших данных, прежде чем создавать карту. Что-то вроде:

export default class App extends Component{
  constructor(props){
      super(props);
      this.state = {
          entry : [],
          anyData: false
      }
  }

  componentDidMount(){
      fetch(process.env.PUBLIC_URL + `./js/data.json`)
      .then(res => res.json())
       .then(json => this.setState( prevState => ({ ...prevState, entry: json, anyData: true })));
  }

  render(){
     if(!anyData) {
       return <Loader />
     }

      return(
          <div>
              <ul>
                  {this.state.entry.map( x => (...))}
              </ul>
          </div>
      )
  }
}

Также есть возможность использовать asyn c метод жизненного цикла:

async componentDidMount() {
  const res = await fetch(...);
  const json  = await res.json();
  this.setState( prevState => ({ ...prevState, entry: json, anyData: true }));
}

Но это не меняет того факта, что это будет сделано после рендеринга.

0 голосов
/ 09 мая 2020

React ожидает, что .map для итеративного рендеринга будет работать только с массивом элементов.

Следовательно, изменение ввода json для возврата массива элементов поможет решить проблему.

Существующий ввод, который не работает с .map:

"entry" : { "1" : [....], "2" : [....] }   --> Input is not an array of items.
                                           --> .map does not support this format

Как заставить его работать с .map ?

"entry" : [ {"1" : {....} , {"2" : {....} ]    --> Input is an array of items. 
                                                --> .map works with this format

Дополнительно: как избежать ошибки «нулевое значение» в методе рендеринга?

Метод рендеринга должен явно проверять нулевое условие перед попыткой для рендеринга элементов. Это можно сделать следующим образом:

render(){
    return(
        <div>
            <ul>
                { (this.state.entry) && 
                  this.state.entry.map( x => (
                    <li>
                        ...
                    </li>
                  ))
                }
            </ul>
        </div>
    )
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...