Reputation: 5968
I want the state to be dependent on server data. I thought of using componentWillMount:
componentWillMount() {
this.setState( async ({getPublicTodosLength}, props) => {
const result = await this.getPublicTodosLengthForPagination();
console.log("result = ", result) // returns the length but not assigned on this.state.getPublicTodosLength
return { getPublicTodosLength: result+getPublicTodosLength }
});
}
getPublicTodosLengthForPagination = async () => { // get publicTodos length since we cannot get it declared on createPaginationContainer
const getPublicTodosLengthQueryText = `
query TodoListHomeQuery {# filename+Query
viewer {
publicTodos {
edges {
node {
id
}
}
}
}
}`
const getPublicTodosLengthQuery = { text: getPublicTodosLengthQueryText }
const result = await this.props.relay.environment._network.fetch(getPublicTodosLengthQuery, {})
return await result.data.viewer.publicTodos.edges.length;
}
There is value but it's not assigned on my getPublicTodosLength state? I think I don't have to bind here since result returns the data I wanted to assign on getPublicTodosLength state
Upvotes: 0
Views: 2314
Reputation: 5968
i decided to make componentWillMount async and it worked well.
this is the code:
componentWillMount = async () => {
let result = await this.getPublicTodosLengthForPagination();
this.setState((prevState, props) => {
return {
getPublicTodosLength: result
}
});
}
Upvotes: 0
Reputation: 1383
If you want your state to be dependent on server data you should use componentDidMount()
.
componentWillMount() is invoked immediately before mounting occurs. It is called before render(), therefore setting state synchronously in this method will not trigger a re-rendering. Avoid introducing any side-effects or subscriptions in this method. This is the only lifecycle hook called on server rendering. Generally, we recommend using the constructor() instead.
componentDidMount() is invoked immediately after a component is mounted. Initialization that requires DOM nodes should go here. If you need to load data from a remote endpoint, this is a good place to instantiate the network request. Setting state in this method will trigger a re-rendering.
Upvotes: 2
Reputation: 1119
Why not rather do something like this?
...
async componentWillMount() {
const getPublicTodosLength = this.state.getPublicTodosLength;
const result = await this.getPublicTodosLengthForPagination();
this.setState({
getPublicTodosLength: result+getPublicTodosLength,
});
}
...
It's simpler and easier to read. I think the problem with the original code is with using async function inside setState(). In transpiled code there is another wrapper function created and then it probably loose context.
Upvotes: 1
Reputation: 2228
May be you could use:
Code snippet:
(async ({getPublicTodosLength}, props) => {
const result = await this.getPublicTodosLengthForPagination();
console.log("result = ", result);
return { getPublicTodosLength: result + getPublicTodosLength }
})).then((v)=> this.setState(v));
Please let me know if that works.
Upvotes: 0