将状态(索引)传递给几个孩子

发布于 2025-01-11 18:48:33 字数 1211 浏览 0 评论 0原文

在学习了如何将状态传递给孩子之后,我现在想知道如何在孩子之间做到这一点。

Parent:

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

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

Child1 (Views):

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

Child2 (Slider):

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

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

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

感谢您的帮助!

After learning how to pass a state to a child, I am now wondering how to do it between children.

Parent:

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

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

Child1 (Views):

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

Child2 (Slider):

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

This returns a rather strange error: undefined is not an object (evaluating 'el.classList').

What I would like to do is pass the index of Views to Slider.

Thanks for all the help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦罢 2025-01-18 18:48:33

Props:

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

数据流

  • 当两个子组件必须共享/使用相同的数据时,父组件会将这些数据传递给子组件。 数据(作为 Props)从上到下流动
  • 现在该数据由父组件拥有。因此,该数据的任何更改也必须由该父组件处理。例如,如果子组件想要更改此数据,它们必须调用父组件的更改处理程序。 将事件流从子级更改为父级

在您的示例中, PostTemplate 是父级,而 Views & 是父级。 Slider 是子项。

  • PostTemplate 拥有并管理索引数据(状态)。
  • PostTemplate 将发送索引数据(状态)到子组件:Views & Slider
  • 现在两个组件的 Props 中都有索引值。
  • 子组件Views需要更改Index的值。因此,父组件还将其自己的索引更改处理程序传递给 Views 组件,
  • 当需要更改 Index 值时,Views 组件会调用从父组件获取的更改处理程序作为 props。

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

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>

在 CodePen 上尝试

Props:

  • Props are data which is passed to the component when it is added to ReactDOM
  • Props are immutable- means component can never change it's own props.

Data Flow:

  • When two child component have to share/use same data, parent component will pass this data to child component. Data (as Props) flows from Up to Down
  • Now this data is owned by Parent component. So any change of this data have to handle by this parent component also. For example, if child component wants to change this Data, they have to call parent's component change handler. Change Event flow from child to parent.

In your example PostTemplate is parent and Views & Slider are child.

  • PostTemplate own and manage index data (state).
  • PostTemplate will send index data (state) to child components: Views & Slider
  • Now both components have index value in their Props.
  • Child component Views need to change the value of Index. So parent component also pass it's own index change handler to Views component
  • Views component calls the change handler it got from it's parent as props when it needs to change Index value.

Here is a working example from your code in question:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文