reactjs - Idiomatic way to dispatch an action on a subcomponent in react redux without passing in props all the way through -
i learning how use react, redux, , react-redux , have rather simple need. want render akin following...
-------------------------------- | title 1 |----------| | | description 1 | button 1 | | | desc... cont. |----------| | |------------------------------| | title 2 |----------| | | description 2 | button 2 | | | desc2... cont. |----------| | |------------------------------| | title 3 |----------| | | description 3 | button 3 | | | desc3... cont. |----------| | |------------------------------|
this represents list of items
. each item
(3 shown in diagram) has title
, description
. when click button want perform action item
, such displaying alert box item's
title.
i managed working sample based on redux tutorial. ended 1 container (smart) component named itemscontainer.tsx
, 2 presentation (dumb) components named itemlist.tsx
(the list) , item.tsx
(an individual item). hierarchically looks this...
app -- itemscontainer ---- itemlist ------ item ------ item
however, redux tutorial required passed onclick
function through each of presentation components via props. if had deeper nesting become burdensome attempting find way.
what have 2 container components itemlistcontainer.tsx
, itemcontainer.tsx
, 2 presentation components itemlist.tsx
, item.tsx
. however, whenever click on button alert box states [object object]
. believe happening receiving button click's event, rather item.id
not sure go here make sure proper function assigned onclick. hierarchically looks this...
app -- itemlistcontainer ---- itemlist ------ itemcontainer -------- item -------- item
the code follows...
// app.tsx import * react 'react'; import { itemlistcontainer } '../additem/itemlistcontainer'; export const app = () => { return <div><itemlistcontainer/></div>; };
// itemlistcontainer.tsx import { itemlist } './itemlist'; import { connect } 'react-redux'; function mapstatetoprops(state: any): { return { items: state.items } } export const itemlistcontainer = connect(mapstatetoprops, null)(itemlist);
// itemlist.tsx import * react 'react'; import { iitems, iitemsummary } '../../data/items/models/item'; import { itemcontainer } './itemcontainer'; export const itemlist = (props: iitems) => { let divstyle = { position: 'block', border: 'solid #aeb0b5 1px', overflowy: 'auto', overflowx: 'hidden', width: 650, height: 300 }; return ( <div style={divstyle}> { props.items.map(function (item: iitemsummary) { return <itemcontainer {...item} />; }) } </div> ); };
// itemcontainer.tsx import { item } './item'; import { iitems } '../../data/items/models/item'; import { removeitem } "../../data/items/actions/initdashboarditems" import { connect } 'react-redux'; function mapstatetoprops(state: any): { return { items: state.items }; } const mapdispatchtoprops = (dispatch: any): => { return { onclick: (id: any) => { alert(id); } }; }; export const itemcontainer = connect( mapstatetoprops, mapdispatchtoprops )(item);
// item.tsx import * react 'react'; import { iitemsummary } '../../data/items/models/item'; export const item = (props: iitemsummary) => { let outerdiv = { position: 'relative', borderbottom: 'solid #aeb0b5 1px', width: '650px' }; let textdiv = { position: 'relative', width: '500px', padding: 5 }; let buttondiv = { position: 'absolute', top: '5px', right: '10px', padding: 5 }; return ( <div style={outerdiv}> <div style={textdiv}><strong>{props.title}</strong></div> <div style={textdiv}>{props.description}</div> <div style={buttondiv}><button onclick={props.onclick}>add chart</button></div> </div> ); };
while need resolve how wire proper function onclick react , redux want know idiomatic react redux way structure code ui described @ top of post?
if had deeper nesting become burdensome attempting find way
you pass in the props as can (using dumb components) @ point free create new smart component can put anywhere (inside dumb component or inside smart component).