Как исправить: setState не работает в gastby? - PullRequest
0 голосов
/ 03 ноября 2019

Я использую gatsby для рендеринга на стороне сервера.

Вот мой код:

class BookSearch extends Component {

    state = {
        search: '',
        books: '',
    };

    componentDidMount() {
        this.loadData()
    }

    loadData () {
        axios.get('/books/list')
            .then(response => {
                this.setState({books: response.data.books});
                console.dir(response.data.books);
            })
            .catch(error => {
                this.setState({error: true});
            });
    }

К сожалению, this.setState не работает в gatsby. componentDidMount не вызывается при загрузке страницы. Что мне делать?

Ответы [ 3 ]

1 голос
/ 03 ноября 2019

Вы упомянули, что используете SSR? Попробуйте использовать componentWillMount в этом случае, поскольку componentDidMount не вызывается в SSR.

Если вы используете версию реакции> 16.3:

При поддержке рендеринга сервера,в настоящее время необходимо предоставлять данные синхронно - для этой цели часто использовался componentWillMount, но конструктор можно использовать в качестве замены. Предстоящие API ожидания сделают асинхронную выборку данных полностью возможной как для рендеринга клиента, так и для сервера.

Ссылка: https://reactjs.org/blog/2018/03/27/update-on-async-rendering.html#fetching-external-data

В вашем случае, я думаю, было бы более разумноиспользуйте статический метод getInitialProps. (https://nextjs.org/learn/basics/fetching-data-for-pages/fetching-batman-shows)

Если вы не очень знакомы с SSR, у Next.js есть отличные учебники: https://nextjs.org/learn/basics/getting-started

Это может вам помочь!

1 голос
/ 03 ноября 2019

Я думаю, что проблема заключается в привязке this к loadData методу.

Вы можете связать это двумя способами.

  1. Bind this в конструкторе,
constructor(props){
   super(props)
   this.state = {
        search: '',
        books: '',
    }
    this.loadData = this.loadData.bind(this)  //Bind this here
}
Или вы можете просто использовать функцию стрелки,
loadData = () => { //Arrow function auto binds `this`
   axios.get('/books/list')
   .then(response => {
        this.setState({
           books: response.data.books
        }); 
        console.dir(response.data.books);
   })
   .catch(error => {
      this.setState({error: true});
   });
}
1 голос
/ 03 ноября 2019

Я думаю, у вас должна быть ошибка? Это потому, что вы не инициализировали error состояние. Вы должны инициализировать состояние, прежде чем сможете их использовать:

state = {
   search: '',
   books: '',
   error: false
};

Я надеюсь, что это может решить проблему. В противном случае я не смогу увидеть никаких проблем в вашем коде.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...