0

I am trying to get React to return a component from within a method in another component. So far I have:

export class Projects extends Component {
    constructor() {
        super();
        this.loadProjects = this.loadProjects.bind(this);
    }

    loadProjects() {
        var userProjectsRef = dbroot.child("users").child(this.props.user.uid).child("projects").ref;
        userProjectsRef.on("child_added", function(snapshot) {
            var id = snapshot.val();
            return (
                <ProjectsRow projectId={id} />
            );
        })
    }

    render() {
        return (
            <div className="container">
                <div className="card">
                    <div className="card-header bg-dark text-light align-center">
                    </div>
                    <ul className="list-group list-group-flush align-left">
                        {this.loadProjects()}
                    </ul>
                </div>
                <AddProjectModal user={this.props.user} />
            </div>
        );
    };
};

I am not sure why the return statement in the loadProjects method is not working. It can return a console.log statement in the same place, however. I also referenced this stack overflow question: React. Creating a function that returns html Any Ideas?

2
  • It looks as though you have an async callback that returns <ProjectsRow>. This won't return in the same context. Commented Sep 10, 2018 at 14:19
  • Hi Zach, your return is not working without errors ? As you are new to react I advise you managing component on event basis without state is an anti-pattern in react. Commented Sep 10, 2018 at 14:19

1 Answer 1

0

Store your project data in the state and you can update the state when a project is added. This way, you can .map() the state in the render function which React will automatically keep calling as you add projects.

export class Projects extends Component {
    constructor() {
        super();

        // set initial empty state
        this.state = {
          projects : []
        };
    }

    // do the state manipulation after the component has mounted
    componentDidMount() {
        var userProjectsRef = dbroot.child("users").child(this.props.user.uid).child("projects").ref;
        userProjectsRef.on("child_added", function(snapshot) {
            var id = snapshot.val();
            const newProject = {id :id};

            // update the state and add the new project
            this.setState((prevState) => ({
              ...prevState, // not needed in this trivial example but would be needed if the state stored other things because setState overwrites the whole state
              projects : [...prevState.projects, newProject] // the updated project is array is the existing array with the new one appended
            }));
        }.bind(this)); // bind this context because the function creates its own this context (or switch to an arrow function)
    }

    // map this.state.projects to <ProjectsRow> components
    render() {
        return (
            <div className="container">
                <div className="card">
                    <div className="card-header bg-dark text-light align-center">
                    </div>
                    <ul className="list-group list-group-flush align-left">
                        {this.state.projects.map((project, index) => <ProjectsRow key={index} projectId={project.id} />)}
                    </ul>
                </div>
                <AddProjectModal user={this.props.user} />
            </div>
        );
    };
};
Sign up to request clarification or add additional context in comments.

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.