react-心得 | 组件间通信的方法 | 实践

176 阅读3分钟

react中,使用函数式组件的写法,使用jsx,return返回类似于vue中的template。

副作用函数useEffect(()=>{},[]),这是一个如果绑定的响应式数据发生变化的时候就会执行的方法。

父子组件通信

在 React 中,组件之间的数据传递通常通过 props 来完成。以下是几种常见的通过 props 传递数据的方法以及相应的示例:

1. 直接传递数据

直接将数据作为属性传递给子组件。

父组件示例


const ParentComponent = (props) => {
  const someData = "Hello from parent!";
  return <ChildComponent data={someData} />;
};

子组件示例


const ChildComponent = (props) => {
  return <div>{props.data}</div>;
};

2. 传递回调函数

将函数作为属性传递给子组件,以便子组件在需要时调用这些函数。

父组件示例

const ParentComponent = () => {
  const handleAction = () => {
    console.log("Action triggered from child!");
  };
  return <ChildComponent onAction={handleAction} />;
};

子组件示例


const ChildComponent = (props) => {
  return <button onClick={props.onAction}>Click Me</button>;
};

3. 传递对象或数组

将对象或数组作为属性传递给子组件,以便子组件可以访问更复杂的数据结构。

父组件示例


const ParentComponent = () => {
  const userData = { name: "Alice", age: 30 };
  return <ChildComponent user={userData} />;
};

子组件示例


const ChildComponent = (props) => {
  return (
    <div>
      <p>Name: {props.user.name}</p>
      <p>Age: {props.user.age}</p>
    </div>
  );
};

4. 使用 children 传递组件

React 允许你将子组件作为特殊的 prop children 传递。

父组件示例


const ParentComponent = () => {
  return (
    <WrapperComponent>
      <div>I am a child component!</div>
    </WrapperComponent>
  );
};

子组件示例


const WrapperComponent = ({ children }) => {
  return <div>{children}</div>;
};

5. 传递函数组件作为属性

将函数组件作为属性传递,子组件根据需要渲染它们。

父组件示例


const ParentComponent = () => {
  const ChildFunction = () => <div>I am a function component!</div>;
  return <WrapperComponent childComponent={ChildFunction} />;
};

子组件示例


const WrapperComponent = ({ childComponent }) => {
  return <div>{childComponent()}</div>;
};

6. 通过 Context API 传递数据

Context 提供了一种在组件树中传递数据的方法,无需手动在每个层级传递 props。

父组件示例


const ThemeContext = React.createContext('light');

const ParentComponent = () => {
  return (
    <ThemeContext.Provider value="dark">
      <ChildComponent />
    </ThemeContext.Provider>
  );
};

子组件示例


const ChildComponent = () => {
  return (
    <ThemeContext.Consumer>
      {theme => <div>The theme is {theme}.</div>}
    </ThemeContext.Consumer>
  );
};

7. 通过状态提升传递数据

在某些情况下,可以将状态提升到共同的父组件中,然后通过 props 向下传递。

共同父组件示例


class CommonParent extends React.Component {
  state = { count: 0 };

  incrementCount = () => {
    this.setState({ count: this.state.count + 1 });
  };

  render() {
    return (
      <>
        <ChildComponentA onIncrement={this.incrementCount} count={this.state.count} />
        <ChildComponentB onIncrement={this.incrementCount} count={this.state.count} />
      </>
    );
  }
}

子组件示例


const ChildComponentA = ({ onIncrement, count }) => {
  return <button onClick={onIncrement}>Count: {count}</button>;
};

const ChildComponentB = ({ onIncrement, count }) => {
  return <div>Sibling sees count: {count}</div>;
};

这些示例展示了在 React 应用中父子组件间数据传递的几种常见方法。每种方法都有其适用场景,您可以选择最适合您当前需求的方法。

注意

  1. 而当函数直接返回 JSX 时,不需要额外的括号来包裹返回的 JSX 元素。 类似这样
const ParentComponent = () => {
  const ChildFunction = () => <div>I am a function component!</div>;
  return <WrapperComponent childComponent={ChildFunction} />;
};

实际应用

在detail页面的使用

面对业务中detail(详情)页面的主要逻辑书写,其实和Form(弹窗,填写表单)是类似的,甚至比Form在交互上更加简单。

在vue中是通过对detail窗口的显示是通过一个Boolean类型数据判断的,这样写代码多一点,面对复杂场景逻辑更容易理解。

// 定义数据
const [activeRow, setActiveRow] = useState({});
const [modal, setModal] = useState(false);
// jsx中使用
(<Button type="link" style={{paddingLeft: 0}} onClick={() => setActiveRow({...row})}>查看资料</Button>)
    
useEffect(() => {
   activeRow.productId && getDetails();
}, [activeRow]);

async function getDetails() {
    const {userId} = activeRow;
    const res = await $POST.certQuery({userId});
    const activeRowDetails = res?.data || {};

    setActiveRowDetails(activeRowDetails);
    setModal(true);
}

在form表单上的搜索上进行了封装,实现了初始值设置,重置,搜索以及风格的统一;得到了SearchBar组件和它的子组件Item

 <SearchBar initData={ininParams} onSearch={handleSearch} onReset={reset}>
      <SearchBar.Item
        label="名称"
        field="name"
        el={
          <Input
            placeholder="根据名称进行搜索,支持模糊匹配"
          />
        }
      />
 <SearchBar>
~~分割线~~
interface ininParams {
   name:undefined
}