0

I'm getting the correct data in component A, now I need to pass that value to component B. In the first component is a click event that receives the clicked item, now I need to pass that clicked value to component B in order to do further formatting.

    class ReportsData extends Component {
    constructor(props) {
    super(props) 
        this.state = {
            value: null
    }
    render() {

    const {reports, employees} = this.props;
    let sortedReports = _.sortBy(reports, function(o) { return new moment(o.date); }).reverse();

    const handleClick = (item) => {
        return item // --> 2011 --> I NEED TO TAKE THIS VALUE AND PASS IT TO ReporstDetails COMPONENT // When I do setState = ({value: item}) error ???
    }

    const listReports = sortedReports.map(item => {

        return (
        <tr key={item.rowNumber}>
            <td>  {item.year}</td>

            <td> {item.month}</td>

            <td> {item.bruto_ukupno}</td>
            <td> {item.neto_plata}</td>
            <td> {item.topli_obrok}</td>

            <td> {item.doprinosi}</td>
            <td> {parseInt(item.ukupno_plata)}</td>

            <td className="table-actions">
                <Link onClick={this.handleClick.bind(this, item.year)}
                    to={`/reports/details`}>
                    <PieChart size="21"/>
                </Link>

            </td>
        </tr>
    )});

    return (
        <div className="container">
        <div>
            <header>
            <h4>A complete list of reports</h4>
            <p>Details available by clicking on an item </p>
            </header>
            <hr />
        </div>

        <table className="table table-striped">
        <thead>
        <tr>
            <th>Year</th>
            <th>Month</th>

            <th>Bruto</th>
            <th>Neto</th>
            <th>Meal</th>

            <th>Taxes</th>
            <th>Employees</th>
            <th>Details</th>
            <th></th>
       </tr>
        </thead>
         <tbody>
            {listReports}
        </tbody>
    </table>
   </div>
    );
}
}

export default ReportsData;

When I try to setState and pass it as props, I'm getting undefined.

I'm a beginner, so please forgive me and help me.

Dženis H.
  • 7,284
  • 3
  • 25
  • 44
  • Store the ID of the clicked item in your component state, then in `render`, pass the relevant item down to the child component through props. If you don't know how to do any of that, I'd *really* recommend reading through the [React tutorial](https://reactjs.org/tutorial/tutorial.html), as it covers all of these topics in a way that's very approachable to newcomers! – Joe Clay Apr 03 '18 at 11:40

5 Answers5

1

Easiest way is to pass your data in state of react-router Link

<Link to={{ pathname: '/reports/details', state: { item } }}>
    <PieChart size="21"/>
</Link>

and console this.props.location.state.item in /reports/details component... you will get your data

Ashh
  • 44,693
  • 14
  • 105
  • 132
  • I'm getting undefined :/ Can you give me a little bit more explanation? Or the issue is with the map function. – Dženis H. Apr 03 '18 at 12:55
  • 1
    please show the code of `handleClick` function and also where you are getting `undefined` – Ashh Apr 03 '18 at 13:17
  • I'll edit this code immediately. Thank you in advance – Dženis H. Apr 03 '18 at 13:38
  • Please show me the way you advise me in the first place.I tried, still nothing. I know I'm messing up, but I need to figure it out. – Dženis H. Apr 03 '18 at 13:51
  • console your `this.props.location` in `/reports/details` component and tell what is coming over there – Ashh Apr 03 '18 at 13:54
  • When I console.log just this.props.location I'm getting undefined – Dženis H. Apr 03 '18 at 14:07
  • if you are getting undefined in `location` then you will have to pass {...this.props} from the parent component... see the updated answer as well – Ashh Apr 03 '18 at 14:09
  • There's a lot of it. It's a full stack app. Some of the code was already written by someone else, and I need to do the extra features. That's the issue. Figuring out the entire process. A lot of libraries too. This is a small portion of the project, but for the most part, these 2-3 components are independent. I was very tired yesterday. Today i'll give it a second try. Wish me luck and thank you for your help.If I get stuck again, I'll let you know :) Cheers – Dženis H. Apr 04 '18 at 04:24
  • After that you can refer how to pass `state` in react router `Link` https://stackoverflow.com/questions/30115324/pass-props-in-link-react-router/30115524 – Ashh Apr 04 '18 at 05:22
  • YES, now it's passing props, but all of them (employees, reports, everything) How can I get that item value that comes from mapping over reports, and when the clik happens i store the item clicked with const handleClick = (item) => { return item } function, but I can't seem to sen that value over to the next component/ route. Thank you man for trying so hard. – Dženis H. Apr 04 '18 at 06:45
  • There was an issue with one of the libraries. --> history.location.state.item <-- ... and the data is shown. I did it man and it's because of your help. I owe you one. Cheers. – Dženis H. Apr 04 '18 at 07:10
  • I am glad that your issue is resolved. Great efforts. Cheers – Ashh Apr 04 '18 at 08:18
1

You can pass the item like this:

<Link to={{"/reports/details", query: your state here}}>
    <PieChart size="21"/>
</Link>

Then in your child component you can use this:

this.props.location.query

Triyugi Narayan Mani
  • 3,039
  • 8
  • 36
  • 56
1

The issue you are facing is what lead to the creation of Redux, MobX and various other flux-like frameworks.

The solution to passing a prop between components that do not have a "parent" - "child" relationship is to use a Store.

Stores contain the application state and logic. Their role is somewhat similar to a model in a traditional MVC, but they manage the state of many objects — they do not represent a single record of data like ORM models do. Nor are they the same as Backbone's collections. More than simply managing a collection of ORM-style objects, stores manage the application state for a particular domain within the application.

You can have multiple Stores in your application where you can group your data and import/use the appropriate one on your components.

Note that you can still use the Store concept even without any of those libraries, example:

class UIStore {
    isModalActive = true;
}

const store = new UIStore();
export default store;

And then simply importing your store in any of your React components

import {UIStore} from 'stores';

And then accessing the property like:

UIStore.isModalActive

Or set its value:

UIStore.isModalActive = false;

My suggestion is though to use one of those libraries since you are going to need it sooner than later even for small size projects. They can notify any of your components that include them if their value changes and re-render them accordingly.

Store example in Redux

Store example in MobX

Sotiris Kiritsis
  • 3,178
  • 3
  • 23
  • 31
0

I am going to give you a suggestion which is just how things are done (in your case) in react. So here it is:

ParentComponent (contains your state: item?)

  • Component A - gets a click handler from props that modifies item in ParentComponent's state

  • Component B - gets the value of item from ParentComponent's state as props

That way when the click handler in Component A gets executed this will trigger a change in the state of ParentComponent, thus the whole thing gets rerendered again and your Component B receives relevant item value.

Hope this helps!

Martin Shishkov
  • 2,709
  • 5
  • 27
  • 44
-1

if component A has some state values if u need to pass to its child component B, then u need to pass it as props.

refer this reactjs.org

Srikanth Gowda
  • 6,163
  • 7
  • 19
  • 34