Phil
Phil

Reputation: 3562

React rendering user list in child component

In my parent component (a search bar component) I have this code which passes an array down to the child component:

When form is submitted I make am axios request to my back-end database

async onFormSubmit(event) {
    event.preventDefault();
    const users = await axios.post("/api/fetchuser", {
      persona: this.state.term
    });

    let userArray = this.state.userArray;
    userArray = users.data.map(user => {
      return user.steamInfo;
    });

    this.setState({ userArray: userArray });
  }

Then I pass down the userArray to the child component:

renderResults() {
    if (this.state.userArray.length > 0) {
      return <UserSearchResult userArray={this.state.userArray} />;
    } else {
      return;
    }
  }

In my child component I have this, keep note of the console.logs as I will show the output afterwards.

class UserSearchResult extends Component {
  async renderUsers() {
    let userList = this.props.userArray;
    console.log(userList);

    userList = userList.map(user => {
      return (
        <Segment>
          <Grid>
            <Grid.Column width={3} style={resultStyle.results}>
              <Image src={user.avatar} fluid />
            </Grid.Column>
            <Grid.Column width={9} />
            <Grid.Column width={3} />
          </Grid>
        </Segment>
      );
    });

    console.log(userList);
    return userList;
  }

  render() {
    return (
      <div>
        {console.log(this.renderUsers())}
      </div>
    );
  }
}

Here is the output:

enter image description here

In the first two console.logs, it prints out exactly what I want, but once I return the userList back to the render function, it changes into promises?

My question is: Why is the userList changing to something else when it's returned to the render function. And how can I render each element in the array according to my jsx?

Upvotes: 2

Views: 1502

Answers (2)

wnamen
wnamen

Reputation: 570

You should remove the async portion. I believe that is what the root of your issue is. I refactored your code below:

class UserSearchResult extends Component {

  render() {
    const { userArray } = this.props
    return (
      <div>
        { userArray.map(user => {
            return (
              <Segment>
                <Grid>
                  <Grid.Column width={3} style={resultStyle.results}>
                    <Image src={user.avatar} fluid />
                  </Grid.Column>
                  <Grid.Column width={9} />
                  <Grid.Column width={3} />
                </Grid>
              </Segment>
            );
          });
        }
      </div>
    );
  }
}

Upvotes: 0

byumark
byumark

Reputation: 298

Try removing async. async makes your function return a promise which isn't necessary.

Also UserSearchResult doesn't need to be a class, just do this.

const UserSearchResult = (props) => {
  const userList = this.props.userArray;
  console.log(userList);

  const UserDetail = ({user}) => {
    return (
      <Segment>
        <Grid>
          <Grid.Column width={3} style={resultStyle.results}>
            <Image src={user.avatar} fluid />
          </Grid.Column>
          <Grid.Column width={9} />
          <Grid.Column width={3} />
        </Grid>
      </Segment>
    );

  console.log(userDetail);

  return (
    <div>
      {userList.map((user, index) => <UserDetail key={index} user={user} /> )}
    </div>
  );
}

Or you could just {userList.map((user, index) => <UserDetail key={index} user={user} /> )} in your original component and make UserDetail it's own component and get rid of the UserSearchResult.

Upvotes: 2

Related Questions