1
votes

I've a problem with React and Redux. Here's the problem:

I have a Component which receives some value from Redux (mapStateToProps)

I have child Component with two functions: render() and renderFoo()

The thing is that I can access the props from the child's render(), but I cannot use it in renderFoo(). Here's the code:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import Child from './child';

class Root extends Component {

  componentWillMount() {
    if(this.props.foo) {
      this.props.getFoo(this.props.foo);
    }
  }

  render () {
    console.log(this.props);
    return (
      <Child foo={this.props.foo}
    )
  }
}


function mapStateToProps(state) {
  return {
    foo: state.foo.value
  };
}

export default connect(mapStateToProps, actions)(Root);

And child component:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';

class Child extends Component {

  componentWillMount() {
    console.log(this.props.foo)
    if(this.props.foo) {
      this.props.getChild(this.props.foo);
    }
  }

  renderFoo() {
    return (
      { this.props.foo }
    )
  }

  render() {
    console.log(this.props.foo) // this works
    return (
      <div>
        { this.props.foo } // this works // this works
        { this.renderFoo() } // this prints nothing
      </div>
    )
  }
}

export default connect(mapStateToProps, actions)(Child);

Any ideas how to make it work?


EDIT:

here's the full code of my child component:

import React, { Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions';
import { Container, Row, Col } from 'reactstrap';
import TimeAgo from 'react-timeago';
import { Link } from 'react-router-dom';

class MediaComments extends Component {

  componentWillMount() {
    console.log(this.props.media)
    if(this.props.media) {
      this.props.getMediaComments(this.props.media);
    }
  }

  renderComments() {
    if(this.props.comments) {
      let c = this.props.comments;
      return [
        Object.keys(c).map(function(key, val) {
          return (
            <div className="news">
              <div className="excerpt">
                <div className="brief">
                  <Link className="name" to={`/profile/${c[key].author_id}`} className="nav-link">{ c[key].first_name } { c[key].last_name }</Link>
                  <div className="date"><TimeAgo date={ c[key].timestamp } /></div>
                </div>
                <div className="added-text">
                  { c[key].comment }
                </div>
              </div>
            </div>
          )
        })
      ]
    } else {
      return [
        <p>No comments</p>
      ]
    }
  }

  render() {
    return (
      <div className="feed">
        { this.props.mediaId }
        { this.renderComments() }
      </div>
    )
  }
}

function mapStateToProps(state) {
  return {
    authenticated: state.auth.authenticated,
    comments: state.comments
  };
}

export default connect(mapStateToProps, actions)(MediaComments);
1
Try putting this.props.foo inside a div in renderFoo() - Héctor
No result. The problem is that I need to use it inside componentWillMount() to get the data that I want to render inside renderFoo(): componentWillMount() { if(this.props.foo) { this.props.getFoo(this.props.foo); } } - delco
Do you get any error - Shubham Khatri
Console is clear. I'm using the latest version of React and Redux. It worked with old version (0.*) - delco

1 Answers

0
votes

See where the issue is, When you write <div>{this.props.foo}</div> it will work because you are rendering a value inside a div.

Now when you write:

renderFoo() {
    return (
      { this.props.foo }
    )
}

That has two issues because meaning of {a} is {a: a}:

1- You are returning an object and trying to render that inside JSX, that will throw error:

Objects are not valid as react child.

2- Object key is also not a valid key, it contains . and it will also throw an error:

Unexpected token .


Solution:

You needs to write it like this:

renderFoo() {
    return ( this.props.foo )
}

Or

renderFoo() {
    return ( <span>{ this.props.foo } </span>)
}