将 state(index) 传递给几个 children

Pass state(index) to several children

在学习了如何将状态传递给 child 之后,我现在想知道如何在 children 之间进行。

Parent:

const PostTemplate = ({ data }) => {
  const [isIndex, setIndex] = useState(0);

  return (
    <>
        <Slider
          setIndex={isIndex}
          {...data}
        />
        <Views
          setIndex={setIndex}
          {...data}
        />
    </>
  );
};

孩子 1(观看次数):

const Views = (data) => {
  return (
      <div>
        {data.views.edges.map(({ node: view }, index) => (
          <div
            onClick={() => {
              data.setIndex(index);
            }}
          >
            <p>Hello</p>
            />
          </div>
        ))}
      </div>
  );
};

Child2(滑块):

const Slider = (data) => {
  return (
      <Swiper initialSlide={data.isIndex}>
        {data.views.edges.map(({ node: view }) => (
          <SwiperSlide>Slide</SwiperSlide>
        ))}
      </Swiper>
  );
};

这个 returns 一个相当奇怪的错误:undefined is not an object (evaluating 'el.classList').

我想做的是将 Views 的索引传递给 Slider。

感谢大家的帮助!

道具:

  • Props 是添加到 ReactDOM 时传递给组件的数据
  • 道具是不可变的——意味着组件永远无法改变它自己的道具。

数据流:

  • 当两个child组件需要share/use相同的数据时,parent组件会将此数据传递给child组件。 数据(作为 Props)从上到下流动
  • 现在此数据归 Parent 组件所有。因此,此数据的任何更改也必须由此 parent 组件处理。例如,如果 child 组件想要更改此数据,则它们必须调用 parent 的组件更改处理程序。 将事件流程从 child 更改为 parent

在您的示例中,PostTemplate 是 parent,ViewsSlider 是 child。

  • PostTemplate 拥有和管理索引数据(状态)。
  • PostTemplate 会将索引数据(状态)发送到 child 组件:Views & Slider
  • 现在两个组件在它们的 Props 中都有索引值。
  • Child 组件 Views 需要更改 Index 的值。所以 parent 组件也将它自己的索引更改处理程序传递给 Views 组件
  • Views 组件在需要更改索引值时调用它从 parent 获得的更改处理程序作为道具。

这是您的相关代码中的一个工作示例:

function Slider(props) {
   return (
     <fieldset>
       <legend>Slider Component </legend>
       <p>Got Index data as Props: {props.index}</p>
     </fieldset>);
}

class PostTemplate extends React.Component {
  constructor(props) {
    super(props);
    this.setIndex = this.setIndex.bind(this);
    this.state = {index: 0};
  }

  setIndex(e) {
    this.setState({index: e.target.value});
  }

  render() {
    const index = this.state.index;
    return (
      <fieldset>
        <legend>PostTemplate Component:</legend>
        <ol>
          <li key={1}> This is parent component which has two child componets: Slider, Views </li>
          <li key={2}> As Index data is used by both of it's child components, Index data is initilized and managed by this component.</li>
          <li key={3}> When a child component needs to use this data (state:index), Posttemplate (parent) will pass the value as props  </li>
          <li key={3}> When a child component needs to change this data (state:index), Posttemplate (parent) will pass the changeHandler as props  </li>
        </ol>
        <Views
           index={index}
           setIndex={this.setIndex}/>
        <Slider
          index={index} />
      </fieldset>
    );
  }
}

function Views(props) {
  return (<fieldset>
            <legend>Views Component </legend>
            <p>Got Index data as Props: {props.index}</p>
            <p>Got index change handler function from Props: {typeof props.setIndex }</p>
            <input
                  value={props.index}
                  onChange={props.setIndex} />
           </fieldset>);
}

ReactDOM.render(
  <PostTemplate />,
  document.getElementById('root')
);
<script src="https://unpkg.com/react/umd/react.development.js">
<script src="https://unpkg.com/react-dom/umd/react-dom.development.js">

<div id="root">
  <!-- This div's content will be managed by React. -->
</div>

Try it on CodePen