Reactjs 从父组件状态填充无状态子组件道具,以显示React中嵌套的无序列表(使用Firebase)

Reactjs 从父组件状态填充无状态子组件道具,以显示React中嵌套的无序列表(使用Firebase),reactjs,state,react-props,Reactjs,State,React Props,我可能在这里遗漏了一些非常简单的东西,但我无法让我的代码正常运行。我试图为每个referenceList显示一个嵌套的无序列表referenceList。我想主要的问题是如何将状态变量referenceListItems传递到子组件referenceListItems const ReferencePage = () => ( <div> <h1>Reference</h1> <Reference /> </di

我可能在这里遗漏了一些非常简单的东西,但我无法让我的代码正常运行。我试图为每个
referenceList
显示一个嵌套的无序列表
referenceList
。我想主要的问题是如何将状态变量
referenceListItems
传递到子组件
referenceListItems

const ReferencePage = () => (
  <div>
    <h1>Reference</h1>
    <Reference />
  </div>
);

class ReferenceBase extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      referenceLists: [],
      referenceListItems: [],
    };
  }

  componentDidMount() {
    this.onListenForReferenceLists();
    this.onListenForReferenceListItems();
  }

  onListenForReferenceLists() {
    this.setState({ loading: true });

    this.unsubscribeReferenceLists = this.props.firebase
      .referenceLists()
      .onSnapshot(snapshot => {
        if (snapshot.size) {
          let referenceLists = [];
          snapshot.forEach(doc =>
            referenceLists.push({ ...doc.data(), uid: doc.id }),
          );
          this.setState({
            referenceLists: referenceLists,
            loading: false
          });
        } else {
          this.setState({ referenceLists: null, loading: false });
        }
    });
  }

  onListenForReferenceListItems() {
    this.unsubscribeReferenceListsItems = this.props.firebase
      .referenceListItems()
      .onSnapshot(snapshot => {
        if (snapshot.size) {
          let referenceListItems = [];
          snapshot.forEach(doc =>
            referenceListItems.push({ ...doc.data(), uid: doc.id }),
          );
          this.setState({
            referenceListItems: referenceListItems,
            loading: false
          });
        } else {
          this.setState({ referenceListItems: null, loading: false });
        }
    });
  }

  componentWillUnmount() {
    this.unsubscribeReferenceLists();
    this.unsubscribeReferenceListsItems();
  }

  render() {
    const { referenceLists, referenceListItems, loading } = this.state;
    return (
      <div>
        {loading && <div>Loading ...</div>}
        {referenceLists ? (
          <ReferenceLists referenceLists={referenceLists} />
        ):(
          <div>There are no reference items ...</div>
        )}
      </div>
    );
  }
}

const Reference = withFirebase(ReferenceBase);

const ReferenceLists = ({ referenceLists }) => (
  <ul className="reference-lists">
    {referenceLists.map( referenceList => (
      <ReferenceList key={referenceList.uid} referenceList={referenceList} />
    ))}
  </ul>
);

const ReferenceList = ({ referenceList }) => (
  <li className="reference">
    <strong>{referenceList.userId}</strong> {referenceList.name}
    <ReferenceListItems />
  </li>
);

const ReferenceListItems =({ referenceListItems }) => (
  <ul className="reference-list-items">
    {referenceListItems.map( referenceListItem => (
      <ReferenceListItem key={referenceListItem.uid} referenceListItem={referenceListItem} />
    ))}
  </ul>
);

const ReferenceListItem = ({ referenceListItem }) => (
  <li className="reference-list-item">
    <strong>{referenceListItem.userId}</strong> {referenceListItem.name}
  </li>
);
const ReferencePage=()=>(
参考
);
类ReferenceBase扩展组件{
建造师(道具){
超级(道具);
此.state={
加载:false,
推荐人:[],
参考列表项:[],
};
}
componentDidMount(){
this.onListenforReferenceList();
this.onListenForReferenceListItems();
}
onListenforReferenceList(){
this.setState({loading:true});
this.unsubscribeReferenceLists=this.props.firebase
.referenceLists()
.onSnapshot(快照=>{
if(snapshot.size){
让引用者=[];
snapshot.forEach(doc=>
push({…doc.data(),uid:doc.id}),
);
这是我的国家({
参考者:参考者,
加载:错误
});
}否则{
this.setState({referenceLists:null,load:false});
}
});
}
onListenForReferenceListItems(){
this.unsubscribeReferenceListsItems=this.props.firebase
.referenceListItems()
.onSnapshot(快照=>{
if(snapshot.size){
让referenceListItems=[];
snapshot.forEach(doc=>
referenceListItems.push({…doc.data(),uid:doc.id}),
);
这是我的国家({
referenceListItems:referenceListItems,
加载:错误
});
}否则{
this.setState({referenceListItems:null,load:false});
}
});
}
组件将卸载(){
此。取消订阅引用列表();
此。取消订阅ReferenceListSites();
}
render(){
const{referenceLists,referencelistems,load}=this.state;
返回(
{正在加载和正在加载…}
{公投者(
):(
没有参考项目。。。
)}
);
}
}
const Reference=withFirebase(ReferenceBase);
const ReferenceLists=({ReferenceLists})=>(
    {referenceList.map(referenceList=>( ))}
); const ReferenceList=({ReferenceList})=>(
  • {referenceList.userId}{referenceList.name}
  • ); 常量ReferenceListItems=({ReferenceListItems})=>(
      {referenceListItems.map(referenceListItem=>( ))}
    ); 常量ReferenceListItem=({ReferenceListItem})=>(
  • {referenceListItem.userId}{referenceListItem.name}
  • );
    通过重新定义引用列表

    let referenceLists = [];
    
    在你的课堂上从来没有设置过。您需要在闭包内返回referencelist,或者在回调中设置类级别变量

    this.referenceLists.push({ ...doc.data(), uid: doc.id })
    

    您没有在父
    ReferenceBase
    组件中显式使用
    ReferenceListItems
    。因此,您只需将其作为属性传递到整个组件树中

      render() {
        const { referenceLists, referenceListItems, loading } = this.state;
        return (
          <div>
            {loading && <div>Loading ...</div>}
            {referenceLists ? (
              <ReferenceLists referenceLists={referenceLists} referenceListItems={referenceListItems} />
            ):(
              <div>There are no reference items ...</div>
            )}
          </div>
        );
    
    render(){
    const{referenceLists,referencelistems,load}=this.state;
    返回(
    {正在加载和正在加载…}
    {公投者(
    ):(
    没有参考项目。。。
    )}
    );
    
    公投者
    constreferencelists=({ReferenceLists,referencelistems})=>(
    
      {referenceList.map(referenceList=>( ))}
    参考者
    const ReferenceList=({ReferenceList,ReferenceList})=>(
    
  • {referenceList.userId}{referenceList.name}
  • );
    ReferenceListItems是在另一个文件中定义的吗?不,我想避免为它创建另一个类,因为它只是一个非常简单的显示。它现在是一个无状态组件。它确实在渲染调用中设置(如果这是您的意思的话).我在显示参考列表时没有问题,只显示子项。对不起,我的错误我认为是您正在寻找的汉克斯!您建议这种方法吗?(看起来有点乏味)您可以交换组件的参数以使您的答案看起来不同。我看不出您的答案与您之前的答案有什么不同。@Pim。非常欢迎您!看看您设置这些组件的方式,我认为这是最容易实现的解决方案。您还可以查看React.Context api:。这允许您将道具从HOC传递到嵌套较深的子组件,而无需繁琐地传递。但是,这将迫使您重新考虑组件树。@Pim啊,我明白了。我认为ReferenceListItems最终需要管理自己的状态等。可能需要将其作为类组件。在任何情况下,pa向它传递道具应该是相同的。@Pim也不要将数据作为道具向下传递,使用redux它很容易实现
    const ReferenceLists = ({ referenceLists, referenceListItems }) => (
      <ul className="reference-lists">
        {referenceLists.map( referenceList => (
          <ReferenceList key={referenceList.uid} referenceList={referenceList} referenceListItems={referenceListItems} />
        ))}
      </ul>
    
    const ReferenceList = ({ referenceList, referenceListItems }) => (
      <li className="reference">
        <strong>{referenceList.userId}</strong> {referenceList.name}
        <ReferenceListItems referenceListItems={referenceListItems}/>
      </li>
    );