<Link/> component stops working when I pass props to it

Viewed 388

Hey I would like to pass data between pages. There are two components, <ResultToolbar /> and <ComparisonTable />. The toolbar contains a <Link/> component that when it is clicked, it will redirect to <ComparisonTable /> with a data passed. The data transfer is done by passing a prop qnaObject into the link component. But when the link prop is passed, the link is not working (the comparisonTable page is not showing, but the url do get changed). When i dont pass any data through the link component, the page redirection works fine (url changed and the comparison table page appears). Any idea why?

here is my <ResultToolbar /> component:

import React from 'react';
import { Link } from 'react-router-dom';

class ResultToolbar extends React.Component {
    render() {
        let {
            qnaObject,
            compareQuery,
            compareTo,
            onCompare,
            quantity,
        } = this.props;

    return (
        <div id='result-toolbar'>
            <div id='toolbar-container'>
                <div id='toolbar-compare-container'>
                    <Link
                        to={{                                                ***this doesn't work***
                            pathname: `${compareTo}/compare${compareQuery}`,
                            qnaObject: qnaObject,
                        }}
                        onClick={onCompare}
                        // to={`${compareTo}/compare${compareQuery}`} ***this works perfectly***
                    >
                        <button id='compare-button'>
                            Compare
                            {quantity === 0 ? '' : ` (${quantity})`}
                        </button>
                    </Link>
                </div>
            </div>
        </div>
    );
}
}

export default ResultToolbar;

and here is my <ComparisonTable /> component:

import ComparisonEntry from './ComparisonEntry';
import ComparisonHeading from './ComparisonHeading';
import TitleBox from '../SearchResult/TitleBox';
import {
    EmailIn,
    PassIn,
    TextIn,
    NumberIn,
    Button,
} from './../SearchForm/FormElements';

class ComparisonTable extends React.Component {
    constructor(props) {
        super(props);
        this.state = {
            products: [],
            atrs: [],
            atrsDesc: [],
            swap: [],
            loading: true,
            category: '',
            catDesc: '',
            buyClicked: false,
            qnaObject: {},
        };
        this.getEntries = this.getEntries.bind(this);
        this.handleBuy = this.handleBuy.bind(this);
        this.handleBack = this.handleBack.bind(this);
    }
getEntries = async () => {
    this.setState({
        loading: true,
    });
    const response = await fetch(
        this.props.location.pathname + this.props.location.search
    );
    const body = await response.json();
    return body;
};

componentDidMount() {
    this.getEntries()
        .then((resolve) =>
            this.setState({
                loading: false,
                products: resolve.products,
                atrs: resolve.atrs,
                atrsDesc: resolve.atrsDesc,
                category: resolve.category,
                catDesc: resolve.description,
            })
        )
        .catch((err) => console.log(err));
}

handleBuy(event) {
    event.preventDefault();
    let toBuy = this.state.products.find(
        (item) => item.id === Number(event.target.name)
    );
    this.setState({
        swap: this.state.products,
        products: [toBuy],
        buyClicked: true,
    });
}

handleBack(event) {
    event.preventDefault();
    let toBuy = [];
    this.setState({
        products: this.state.swap,
        swap: toBuy,
        buyClicked: false,
    });
}

render() {
    console.log(this.props.location.qnaObject);
    let highlightEntry = true;
    let comparisonEntries = this.state.atrs.map((item, index) => {
        highlightEntry = !highlightEntry; //this is to alternate the shades on each entry to enhance readability
        return (
            <ComparisonEntry
                key={index}
                attribute={item}
                description={this.state.atrsDesc[index]}
                comparees={this.state.products}
                color={highlightEntry}
            />
        );
    });

    return (
        <div id='comparison-page'>
            <TitleBox title={this.state.category} text={this.state.catDesc} />

            <div id='comp-sub-container'>
                <div id='comp-table-order-container'>
                    <div id='comparison-table'>
                        <div
                            id='review-reminder'
                            style={{ display: this.state.buyClicked ? 'block' : 'none' }}
                        >
                            Check the product below
                        </div>

                        <ComparisonHeading
                            dispButt={this.state.buyClicked}
                            comparees={this.state.products}
                            onBuy={this.handleBuy}
                            onBack={this.handleBack}
                        />

                        {comparisonEntries}

                        <div
                            className='loader'
                            style={{
                                display: this.state.loading ? 'block' : 'none',
                                margin: '10rem 5rem',
                            }}
                        ></div>
                    </div>

                    <div
                        id='order-page'
                        style={{
                            display: this.state.buyClicked ? 'inline-flex' : 'none',
                        }}
                    >
                        <div id='order-page-container'>
                            <EmailIn label='Email' />
                            <TextIn label='Name' />
                            <PassIn label='password' />
                            <NumberIn label='number' />
                            <Button label='buy' />
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
}
}

export default ComparisonTable;
1 Answers

If you're trying to pass data in the route push that occurs from a Link then you need to pass it in the correct property.

Link to-object

An object that can have any of the following properties:

  • pathname: A string representing the path to link to.
  • search: A string representation of query parameters.
  • hash: A hash to put in the URL, e.g. #a-hash.
  • state: State to persist to the location.
<Link
  to={{
    pathname: `${compareTo}/compare${compareQuery}`,
    state: { qnaObject },
  }}
  onClick={onCompare}
>

To access on the receiving route

props.location.state.qnaObject
Related