1

The state gets passed in via props (selectedCategory). Using axios to get an array... it comes back, I can console.log it within the function. I'd like to assign it to a variable and then outside of the function I'd like to map over it. But it is unavailable (undefined)

import React from 'react';
import SearchCategoryMembers from '../libs/category-members';

import MemberItem from './member_item';

const Members = ({ selectedCategory }) => {
  if (!selectedCategory) {
    return <div className="none" />;
  }

  SearchCategoryMembers({ categoryTitle: selectedCategory.title }, members => {
    console.log(members);
  });

  // members not available to map over outside of function

  return <ul className="member-list" />;
};

export default Members;
3
  • members not available to map over outside of function - well, why not map over it inside the function Commented Nov 7, 2017 at 22:32
  • I need to return it to use it inside of the ul one way or the other... Commented Nov 7, 2017 at 22:34
  • 1
    it's hard to give you any guidance, because I can't imagine what you want to do Commented Nov 7, 2017 at 22:36

3 Answers 3

3

What you're trying to do is a common paradigm in React. You're asking for data from some outside source, and then once it's retrieved my guess is you want to render it in this component but you're trying to use a stateless component to do it. You need a way of keeping track of when the callback in SearchCategoryMembers has completed. You have to use state.

import React, { Component } from 'react';
import SearchCategoryMembers from '../libs/category-members';

import MemberItem from './member_item';

class Members extends Component {

  constructor(props) {
    super(props);

    // We'll put our members here once we get them back
    this.state = { };
  }

  // This is generally where you want to make api calls in the react lifecycle
  componentDidMount() {
    const selectedCategory = this.props.selectedCategory;
    if (!selectedCategory) return;
    SearchCategoryMembers(
      { categoryTitle: selectedCategory.title },
      members => {
        // now we have our members data, set it on state
        this.setState({ members: members });
        // or fancy es6 shorthand: this.setState({ members });
      }
    );
  }

  render() {
    // my guess is you want to render something about the members here
    if (!this.state.members) return null;
    return (
      <ul>
        {this.state.members.map((member) => <li>{member.name}</li>)}
      </ul>
    );
  }

}

export default Members;
Sign up to request clarification or add additional context in comments.

Comments

1

The issue is the SearchCategoryMembers is an asynchronous function so we need to wait for the data to be returned before we can use the members data.

To do this we can fetch the data from the asynchronous API request and update the state of the parent component. We'll initially set the members state to an empty array. When the component mounts we'll request the data and when it's returned we'll update the members state, which is then passed to the <Members /> component which then renders the members array passed to it.

Here's a simplified working example:

function SearchCategoryMembers() {
  return axios.get('https://jsonplaceholder.typicode.com/posts');
}

class MembersWrapper extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      members: []
    }
  }
  
  componentDidMount = () => {
    SearchCategoryMembers().then(data => {
      this.setState({
        members: data.data
      })
    });
  }

  render() {
    return (
      <Members members={this.state.members} />
    )
  }
}

function Members(props) {
  return (
    <ul>
      {props.members.map((member, id) => <li key={id}>{member.title}</li>)}
    </ul>
  )
}
ReactDOM.render(<MembersWrapper />, document.getElementById("app"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.17.0/axios.js"></script>

<div id="app"></div>

Comments

-2

try Members.props.selectedCategory

Comments

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.