Reactjs: How to download data to download before the component is installed?

Something strange happens, I read the React docs and they talk about the life cycle and how you can do something before your component is rendered. I try, but everything I try fails, the component always renders first after calls to componentenWillMount, .. didMount, etc., And after calling these functions, the rendering is done again.

I need to load the data first to fill this state, because I do not want the initial state to be null , I want it with the data since the initial rendering.

I use Flux and Alt, here

act

 @createActions(flux) class GetDealersActions { constructor () { this.generateActions('dealerDataSuccess', 'dealerDataFail'); } getDealers (data) { const that = this; that.dispatch(); axios.get(`${API_ENDPOINT}/get-dealers/get-dealers`) .then(function success (response) { console.log('success GetDealersActions'); that.actions.dealerDataSuccess({...response.data}); }) } } 

then store

 @createStore(flux) class GetDealersStore { constructor () { this.state = { dealerData : null, }; } @bind(GetDealersActions.dealerDataSuccess) dealerDataSuccess (data) { this.setState({ dealerData : data, }); } } 

and component

 @connectToStores export default class Dealers extends Component { static propTypes = { title : React.PropTypes.func, } static contextTypes = { router : React.PropTypes.func, } constructor (props) { super(props); this.state = { modal : false, dealerData : this.props.dealerData, } } componentWillMount () { GetDealersActions.getDealers(); this.setState({ dealerData : this.props.dealerData.dealersData, }) } static getStores () { return [ GetDealersStore ]; } static getPropsFromStores () { return { ...GetDealersStore.getState(), } } render () { return (<div> <div style={Styles.mainCont}> {!!this.props.dealerData ? this.props.dealerData.dealersData.map((dealer) => { return (<div>HERE I AM RENDERING WHAT I NEED</div>); }) : <p>Loading . . .</p> } </div> </div> ); } } 

as you can see in the component part, I have this

  constructor (props) { super(props); this.state = { modal : false, dealerData : this.props.dealerData, } } componentWillMount () { GetDealersActions.getDealers(); this.setState({ dealerData : this.props.dealerData.dealersData, }) } 

which tells me that dealerData is undefined or can not read property of null .

All I need to do is know the technique in which I can get the data before the initial rendering happens. Therefore, I can populate state and start working with this data.

+5
source share
2 answers

The reaction ensures that state assignments in componentWillMount will take place before the first rendering. As well said in the comments:

It is called once, both on the client and on the server, immediately before the start of rendering. If you call setState in this method, render () will see the updated state and will be executed only once, despite the state change.

However, the asynchronous actions requested there will not immediately update your store. Call GetDealersActions.getDealers(); will cause the repository to be updated with new content, but the response will arrive only later in the event queue. This means that this.props.dealersData does not change during the function, and setState will try to read the "dealersData" property of the undefined property. Despite this, the requested content may not be visible on the first render.

My advice is the same as in a similar question . Preventing a component from providing this content until it becomes available, as you did, is a suitable thing in the program. Also visualize the bootloader until your "dealersData" arrives.


To solve your specific problem, remove setState from componentWillMount . Everything should work well if your parent component listens for the changes correctly and distributes them to the requisites for the children.

 componentWillMount () { GetDealersActions.getDealers(); } 
+3
source

The best answer that I use to get data from the server and display it

 constructor(props){ super(props); this.state = { items2 : [{}], isLoading: true } } componentWillMount (){ axios({ method: 'get', responseType: 'json', url: '....', }) .then(response => { self.setState({ items2: response , isLoading: false }); console.log("Asmaa Almadhoun *** : " + self.state.items2); }) .catch(error => { console.log("Error *** : " + error); }); })} render() { return( { this.state.isLoading && <i className="fa fa-spinner fa-spin"></i> } { !this.state.isLoading && //external component passing Server data to its classes <TestDynamic items={this.state.items2}/> } ) } 
+1
source

Source: https://habr.com/ru/post/1233564/


All Articles