0

Hello I'm trying to learn react native from Stephen Grider's react-native course.I'm stuck to load data from my webservice and list them by using redux and lodash .I can successfully get data and can see it in render (console.log) ,and but my props always is null in componentDidUpdate or componentWillMount . Any help is appreciated,thanks. Reducer is like this;

    import { TEST_FETCH, TEST_LOAD } from "../actions/types";

const INITIAL_STATE = { dataSource: [] };

export default (state = INITIAL_STATE, action) => {
  switch (action.type) {
    case TEST_FETCH:
      return { ...state, loading: false, dataSource: action.payload.data };
    case TEST_LOAD:
      return { ...state, loading: true, error: "" };
    default:
      return state;
  }
};

and action is ;

    import { TEST_LOAD, TEST_FETCH } from "./types";
export  const  getdata = ( ) => {
  return  dispatch => {
    dispatch({ type: TEST_LOAD });
     fetch("http://myserver/getdata", {
      method: "GET",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json"
      }
    })
      .then(response => {
        return response.json();
      })
      .then(responseData => {
        return responseData;
      })

      .then(data => {
        // return data;
        dispatch({ type: TEST_FETCH, payload: data });
      });
  };
};

and page is ;

       import _ from 'lodash';
    import React, { Component } from "react";
    import { View, Text, ListView } from "react-native";
    import { connect } from "react-redux";
    import { getdata } from "../actions";

    class testList extends Component {
      componentWillMount() {
       this.props.getdata();
      }
      componentDidMount() {
       console.log(this.props.myarray ); // myarray is empty
        this.createDataSource(this.props.myarray);
      }

      componentDidUpdate() {
       console.log(this.props.myarray ); // I tried this but still myarray is empty
        this.createDataSource(this.props.myarray);
      }
      createDataSource({ dtsource }) {
// sure dtsource is null too
         const ds = new ListView.DataSource({
          rowHasChanged: (r1, r2) => r1 !== r2});
         this.dataSource = ds.cloneWithRows(dtsource);
      }
      render() {
    console.log(this.props.myarray); // if I write here,I can see my json's output
        return <View>
            <Text>Employee List</Text>
            <ListView dataSource={this.props.myarray} renderRow={rowData => <Text
                >
                  {rowData}
                </Text>} />
          </View>;
      }
    }

    const mapStateToProps = state => {
      const myarray= _.map(state.testForm.dataSource, function(v) {
        return { ...v };
      });
          return { myarray};
    };
    export default connect(mapStateToProps , { getdata })(testList);
7
  • You should dispatch your action from componentDidMount. See reactjs.org/docs/react-component.html#componentwillmount. Commented Dec 30, 2017 at 20:16
  • Where is this.props.arr1 coming from? Commented Dec 30, 2017 at 20:24
  • @CarlosC sorry ,i forget to change it while writing here.It is myarray Commented Dec 30, 2017 at 20:29
  • You're passing mapDispatchToProps in to connect(). It should be mapStateToProps. Commented Dec 30, 2017 at 20:38
  • @AdamKipnis I correct that, but I wrote this wrong here.Sorry Commented Dec 30, 2017 at 20:42

1 Answer 1

1

I would recommend you to use a FlatList since ListView is deprecated and has bad performance. In the meantime, you can use the code snippet below to pass the correct object to dataSource. You might need to add some null checks depending on the state of the data you pass to myarray.

import _ from 'lodash';
import React, { Component } from "react";
import { View, Text, ListView } from "react-native";
import { connect } from "react-redux";
import { getdata } from "../actions";

class testList extends Component {

  constructor(props) {      
    super(props);               
    this.state = {      
    dataSource: new ListView.DataSource({       
      rowHasChanged: (r1, r2) => r1 !== r2}).cloneWithRows(props.myarray ? props.myarray : [])      
    };      
  }

  componentDidMount() {
    this.props.getdata();
  }

  componentDidUpdate() {
    this.setState({     
       dataSource: this.state.dataSource.cloneWithRows(props.myarray ? props.myarray : [])      
    });
  }

  render() {
    return <View>
        <Text>Employee List</Text>
        <ListView dataSource={this.props.myarray} renderRow={rowData => <Text
            >
              {rowData}
            </Text>} />
      </View>;
  }
}

const mapStateToProps = state => {
  const myarray =  _.map(state.testForm.dataSource, function(v) {
    return { ...v };
  });
      return { myarray};
};
export default connect(mapStateToProps , { getdata })(testList);
Sign up to request clarification or add additional context in comments.

2 Comments

thx for your comment ,I tried it but got error "TypeError: Cannot convert undefined or null to object" . Maybe my problem is something different,I'm very very new to react so still dont know some basic stuffs I guess. By the way I can see ,my json data in mapStateToProps ; console.log(state.testForm.dataSource)
I updated to do a null/undefined check. I mentioned in my comment to do something like that if necessary based on the state of your data.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.