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

Populating stateless child component props from parent component state to display nested unordered list in React (with Firebase)

我可能在这里遗漏了一些非常简单的东西,但我无法将我的代码正确地 运行。我正在尝试为每个 referenceList 显示 referenceListItems 的嵌套无序列表。我想主要的问题是如何将状态变量 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>
);

通过重新声明 referenceList

let referenceLists = [];

它永远不会在您的 class 中设置。您需要 return 闭包内的 referenceLists 或在回调

中设置 class level 变量
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>
    );

参考文献

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>
);