The version of react-router-dom is v6 and I'm having trouble with passing values to another component using Navigate.
I want to pass selected rows to another page called Report. But, I'm not sure I'm using the right syntax for navigate
method and I don't know how to get that state in the Report component.
Material UI Table: I'm trying to use redirectToReport(rowData)
in onClick
parameter.
function TableRows(props){
return (
<MaterialTable
title="Leads"
columns={[
...
]}
data = {props.leads}
options={{
selection: true,
filtering: true,
sorting: true
}}
actions = {[{
position: "toolbarOnSelect",
tooltip: 'Generate a report based on selected leads.',
icon: 'addchart',
onClick: (event, rowData) => {
console.log("Row Data: " , rowData)
props.redirect(rowData)
}
}]}
/>
)}
LeadTable component
export default function LeadTable(props) {
let navigate = useNavigate();
const [leads, setLeads] = useState([]);
const [loading, setLoading] = useState(true);
async function fetchUrl(url) {
const response = await fetch(url);
const json = await response.json();
setLeads(json[0]);
setLoading(false);
}
useEffect(() => {
fetchUrl("http://localhost:5000/api/leads");
}, []);
function redirectToReport(rowData) {
navigate('/app/report', { state: rowData }); // ??? I'm not sure if this is the right way
}
return(
<div>
<TableRows leads={leads} redirect={redirectToReport}></TableRows>
</div>
)}
Report component
export default function ReportPage(state) {
return (
<div>
{ console.log(state) // This doesn't show anything. How to use the state that were passed from Table component here?}
<div className = "Top3">
<h3>Top 3 Leads</h3>
<ReportTop3 leads={[]} />
</div>
</div>
);}
Your navigate('/app/report', { state: rowData });
looks correct to me.
If you need state, use
navigate('success', { state })
.
interface NavigateFunction { ( to: To, options?: { replace?: boolean; state?: any } ): void; (delta: number): void; }
Your ReportPage
needs to be rendered under the same Router
that the component doing the push is under.
Route props are no longer passed to rendered components, as they are now passed as JSX literals. To access route state it must be done so via the useLocation
hook.
function ReportPage(props) {
const { state } = useLocation();
console.log(state);
return (
<div>
<div className="Top3">
<h3>Top 3 Leads</h3>
<ReportTop3 leads={[]} />
</div>
</div>
);
}
If the component isn't able to use React hooks then you still access the route state via a custom withRouter
Higher Order Component. Here's an example simple withRouter
HOC to pass the location
as a prop.
import { useLocation, /* other hooks */ } from 'react-router-dom';
const withRouter = WrappedComponent => props => {
const location = useLocation();
// other hooks
return (
<WrappedComponent
{...props}
{...{ location, /* other hooks */ }}
/>
);
};
Then access via props as was done in pre-RRDv6.
class ReportPage extends Component {
...
render() {
console.log(this.props.location.state);
return (
<div>
<div className="Top3">
<h3>Top 3 Leads</h3>
<ReportTop3 leads={[]} />
</div>
</div>
);
}
}