Ho un componente che ha figli dello stesso tipo del componente stesso. Posso rendere anche i bambini, ma i bambini non riescono ad accedere alla loro fetta di stato. Sto usando reagire con ReduxPassa stato a componente annidato ricorsivamente in React/Redux
export class Material extends React.Component {
constructor(props) {
super(props)
this.renderChild = this.renderChild.bind(this)
this.getNestedItems = this.getNestedItems.bind(this)
}
static propTypes = {
parentId: PropTypes.number,
id: PropTypes.number.isRequired,
name: PropTypes.string.isRequired,
subtext: PropTypes.string.isRequired,
childIds: PropTypes.arrayOf(PropTypes.number.isRequired),
fileType: PropTypes.string.isRequired
}
// This is where I am having trouble.
// Shouldn't the props be accessible from state itself?
renderChild = (id, childId) => (
<Material key={childId}
id={childId}
parentId={id}
name={name}
subtext={subtext}
fileType={fileType}
/>
)
getNestedItems = (id, childIds) => {
console.log("id: " + id)
console.log("childIds: " + childIds)
var childItems = []
for(var i=0; i < childIds.length; i++){
var child = this.renderChild(id, childIds[i])
childItems.push(child)
}
return childItems
}
render(){
let childItems = []
if(this.props.childIds){
childItems = this.getNestedItems(this.props.id, this.props.childIds)
}
return(
<ListItem
leftAvatar={<Avatar icon={fileType.length === 0 ? <FileFolder /> : <ActionAssignment />} />}
rightIcon={fileType.length === 0 ? <AddCircle /> : <ActionInfo />}
primaryText={name}
secondaryText={subtext}
initiallyOpen={fileType.length === 0} // fileType is empty if it is a folder
primaryTogglesNestedList={fileType.length === 0}
nestedItems={childItems} // one has to pass an array of elements
/>
)
}
}
const mapStateToProps = (state, ownProps) => {
return {
id: ownProps.id,
name: state.Material[ownProps.id].name,
subtext: state.Material[ownProps.id].subtext,
childIds: state.Material[ownProps.id].childIds,
fileType: state.Material[ownProps.id].fileType,
}
}
export default connect(
mapStateToProps
)(Material)
Inoltre, sto facendo uso di ListItem from Material-ui (questi sono in ultima analisi, resi all'interno di un componente List) e il mio codice è fortemente influenzato dal tree-view example nella repo ufficiale redux. Il mio stato si presenta così:
const initialState = {
0: {
id: 0,
name: 'Root',
subtext: 'Some subtext',
fileType: '',
childIds: [1]
},
1: {
id: 1,
name: 'Child',
subtext: 'Child subtext',
fileType: 'png',
childIds: []
}
}
Lo stato mostrato ha la stessa struttura come nell'esempio vista ad albero
Sì funziona! La tua risposta mi ha fatto capire quale fosse l'errore. Ho anche diviso il mio componente in un componente di presentazione e un contenitore, ma stavo rendendo il componente di presentazione come figlio nidificato invece del contenitore. – AndyFaizan
Questo ha risolto lo stesso identico problema per me, grazie. Ero curioso di sapere perché questo non è gestito da 'mapStateToProps' che già associamo al componente. Anche se ho digitato la frase precedente ho capito che questo è esattamente perché abbiamo solo "mapStateToProps' per l'esportazione. I bambini annidati in modo ricorsivo invocano la funzione componente * prima * dell'esportazione, e quindi necessitano di un'applicazione separata di 'mapStateToProps'. –