Phillip R Phillip R - 6 months ago 34
React JSX Question

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?

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download