繁体   English   中英

在 React 元素之间传输数据

[英]Transferring data between React elements

试图弄清楚如何在兄弟组件之间传输数据。 想法是这样的:您需要确保只有一个子组件具有“活动” class(只能选择一个 div)。 这是代码: https://codepen.io/slava4ka/pen/rNBoJGp

import React, {useState, useEffect} from 'react';
import styleFromCss from './Garbage.module.css';

const ChildComponent = (props) => {
    const [style, setStyle] = useState(`${styleFromCss.childComponent}`);
    const [active, setActive] = useState(false)
const setActiveStyle = () => {
    console.log("setActiveStyle");
    if (!active) {
        setStyle(`${styleFromCss.childComponent} ${styleFromCss.active}`)
        setActive(true)
    } else {
        setStyle(`${styleFromCss.childComponent}`);
        setActive(false)
    }
};

//console.log(props);
console.log(`id ${props.id} style ${style}`);
return (
    <div className={style} onClick={() => {
        props.updateData(props.id, () => setActiveStyle())
    }}>
        <h3>{props.name}</h3>
    </div>
   )
 };

const ParentComponent = (props) => {

const state = [{'id': 0, 'name': 'один'}, {'id': 1, 'name': 'два'}, {'id': 2, 'name': 'три'}];

const [clicked, setClicked] = useState(null);

const highlight = (id, makeChildActive) => {
    //console.log("click! " + id);
    setClicked(id);
    makeChildActive();
};

return (
    <div>
        {state.map(entity => <ChildComponent updateData={highlight}
                                             key={entity.id}
                                             id={entity.id}
                                             name={entity.name}
                                             isActive={(entity.id === 
     clicked) ? styleFromCss.active : null}
        />)}
    </div>
   )
};

export default ParentComponent;

styleFromCss.module.css:

.childComponent{
   width: 200px;
   height: 200px;
   border: 1px solid black;
   margin: 10px;
   float: left;
   text-align: center;
 }

.active{
    background-color: blueviolet;
 }

我试图通过钩子而不是类来实现这一点。 结果,当您单击所选组件时,其类会发生变化,而其兄弟姐妹则不会发生任何事情。 据我了解,他们根本不重绘。 问题是如何修复它? 这种方法对于实现给定目标是否正确? 或者我的想法从根本上是错误的,我将不胜感激)))

您需要将 function 从处理父组件中 state 更改的父组件向下传递给子组件,以获取确定哪个 id 为“active”的 state。 然后将 activeId 作为道具传递给孩子。 在孩子中,将 id 与 activeId 进行比较,并相应地应用 class。

您不能使用Child的onClick方法将样式设置为单击一个Child时,其他Child不知道:((

相反,当您单击一个子级时,它会告诉父级它被单击(您已经使用 setClicked() 正确执行此操作),然后父级可以告诉每个子级它们是否处于活动状态(通过传递 IsActive 布尔值),并且每个Child 使用它的 props.isActive boolean 来设置它的样式:D

const ChildComponent = (props) => {

    let style = 'childComponent'
    if (props.isActive) style = style + ' active'

    return (
        <div className={style} onClick={() => {
            props.updateData(props.id)
        }}>
            <h3>{props.name}</h3>
        </div>
    )
};


const ParentComponent = (props) => {
    const state = [{'id': 0, 'name': 'один'}, {'id': 1, 'name': 'два'}, {'id': 2, 'name': 'три'}];

    const [clicked, setClicked] = React.useState(null);

    const highlight = (id) => {
        setClicked(id);
    };

    return (
        <div>
            {state.map(entity =>
                <ChildComponent updateData={highlight}
                                key={entity.id}
                                id={entity.id}
                                name={entity.name}
                                isActive={entity.id === clicked}
                />
            )}
        </div>
    )
};


ReactDOM.render(
    <ParentComponent/>,
    document.getElementById('root')
);

正确,这是错误的思考方式。 如果您希望一次只选择一个孩子,则应在父项中保留“选择了哪个孩子”数据。 每个孩子也不应该管理自己突出显示的 state 版本; 相反,它应该是给每个孩子的道具(每个孩子都是纯 function。)试试这个:

const ChildComponent = props => {
  return (
    <div
      className={'childComponent' + (props.isActive ? ' active' : '')}
      onClick={() => props.setHighlighted(props.id)}
    >
      <h3>{props.name}</h3>
    </div>
  );
};

const ParentComponent = props => {
  const state = [
    { id: 0, name: 'один' },
    { id: 1, name: 'два' },
    { id: 2, name: 'три' }
  ];

  const [clicked, setClicked] = React.useState(null);

  return (
    <div>
      {state.map(entity => (
        <ChildComponent
          setHighlighted={setClicked}
          key={entity.id}
          id={entity.id}
          name={entity.name}
          isActive={entity.id === clicked ? 'active' : null}
        />
      ))}
    </div>
  );
};

ReactDOM.render(<ParentComponent />, document.getElementById('root'));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM