0

I have a child component:

import * as React from 'react';
import Select from 'react-select';

import { Link } from 'react-router-dom';
import { Button } from '../controls/Button/Button';
import { ISelectedItem } from '../../interfaces/ISelectedItem';

import * as service from "../../helpers/service";

export interface IProps{
    onClickRender: (selectedItem: ISelectedItem) => void;
}

export interface IState {
    customerData: ISelectedItem[];
    selectedItem: ISelectedItem;
}

export class DropDownSearch extends React.Component<{}, IState>{
    constructor(props: any) {
        super(props);
        this.state = ({
            customerData: [],
            selectedItem: { shortName: '', description: '' }
        });
    }

    componentDidMount() {
        service.fetchJson<ISelectedItem[]>("/api/customers")
            .then((json) =>{
                this.setState({
                    customerData: json
                });
            });
    }

    handleChange = (selectedItem: any) => {
        this.setState({
            selectedItem
        });
    }

    render() {
        const { selectedItem } = this.state;
        const value = selectedItem && selectedItem;

        return (
            <div>
                <Select
                    name="form-field-name"
                    value={this.state.selectedItem}
                    onChange={this.handleChange}
                    options={this.state.customerData}
                    labelKey="shortName"
                />


<Link to={{
 path "/dashboard/" + this.state.selectedItem.shortName,
 state: { detail : this.state.selectedItem }
}}>
                    <Button type="button" className="btn btn-primary" caption="Search" />
                </Link>
            </div>
        );
    }
}

I want to pass the this.state.selectedItem to the Dashboard component, which is part of the Route config in the parent component below:

import * as React from 'react';

import { Navbar } from './Navbar/Navbar';
import { ShortNameSelector } from './ShortNameSelector/ShortNameSelector';
import { Dashboard } from './Dashboard/Dashboard';
import { BrowserRouter, Route, Switch } from 'react-router-dom';

export class App extends React.Component<{},{}>{
    render(){
        return(
            <BrowserRouter>
                <div className="container">
                    <Navbar />
                    <div className="col-lg-12">
                        <Switch>
                            <Route exact path="/" component={ShortNameSelector} />
                            <Route path="/dashboard" component={Dashboard} />
                        </Switch>
                    </div>
                </div>
            </BrowserRouter>
        );
    }
}

Problem is I'm using Routes to switch components on the button click in my child components. How do I pass the this.state.selectedItem object from child to the Dashboard component (shown in parent component) via Routes?

EDIT:

So I put the state attribute inside Link tag and referenced it in Dashboard component like this.props.location.state.detail and it works. But now I want to persist the data in that route/Dashboard component when I open that link in a new page. How do I go about it?

blankface
  • 5,757
  • 19
  • 67
  • 114
  • Possible duplicate of https://stackoverflow.com/questions/44121069/how-to-pass-params-with-history-push-in-react-router-v4/45263164#45263164 – Shubham Khatri Jan 24 '18 at 04:15
  • @ShubhamKhatri Based on the link you provided, I made some progress. But now I want to persist the data. Please check the original post for more detail. Thanks! – blankface Jan 24 '18 at 06:37

2 Answers2

0

You can use like this

<Route path="/dashboard/:selectedItem" component={Dashboard} />

So you can dynamically update the selected item in the DOM URL and when you click it, you can use 'this.props.match.params.id' in the 'Dashboard' component to access that value.

Lakshitha Ruwan
  • 949
  • 1
  • 9
  • 12
  • `selectedItem` is an object. in the URL I only want `selectedItem.shortName` but in the page I also need `selectedItem.description`. – blankface Jan 24 '18 at 06:38
  • Then I think you can add those parameters as query string parameters in the URL it self and read them from the 'Dashboard' component ? – Lakshitha Ruwan Jan 24 '18 at 06:57
  • Like I said, I only need to put `selectedItem.shortName` as query string param in URL, not the `selectedItem.description`. How do I get the value for `selectedItem.description` then? – blankface Jan 24 '18 at 07:44
  • You could update session storage with that object (id & description) when you updating the state variable. so session storage value can be used from anywhere. https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage OR If you have used Redux, you could update the store and access it from dashboard component. – Lakshitha Ruwan Jan 24 '18 at 08:06
0

Passing object between components via Router in React: I have copied fragment of codes from my project, might be useful to you.

  1. I use NavLink, which supposed pass an object to my InfoComponent
<NavLink to={{
            pathname: /menu/${props.data.code},
            search: '',
            state: { selectedMenu: props.data }
          }} color="info" className="btn btn-info btn-success mx-4">Info</NavLink>
  1. In my router, I then received the passed argument in Router as follows, added console log for more clarity
<Route path="/menu/:item" render={(props) => {
              console.log("::::::::: " + JSON.stringify(props.location.state.selectedMenu));
              return (<InfoComponent selectedMenu={props.location.state.selectedMenu} />);
            }} />
DBedrenko
  • 4,871
  • 4
  • 38
  • 73