react项目组件通信

一、父-子通信

React 的数据流是单向的,父组件可以直接将 this.props 传入子组件

1、父组件

场景需求:

  • 添加成功后,更新接口
  • 关闭模态框
  • modalStatus, bankId, currentData(对象), onDataChange(function), onOk(function)

解决方法:

  • 传入函数子组件调用
  • onDataChange={() => this.getData()}
  • onOk={() => cancel()}
componentDidMount(){
    this.getData()
}
// 更新新接口
getData(){
    if(this.state.currentId){
        api.bankApproveQueryAllDetail(this.state.currentId).then((data: any) => {
            this.setState({
                list: data.data || []
            })
        })
    }
}

render(){}

const cancel = () => {
    this.setState({
        isModalVisible: false  
    })
}
回显场景
<TabPane tab={item.isDefault?'默认模板':item.templateName} key={item.approveId}>
    <AddTemplate modalStatus={'update'} bankId={this.state.currentId} currentData={item} onDataChange={() => this.getData()}></AddTemplate>
</TabPane>
添加场景
<Modal title="添加模板" width={'830px'} footer={null} visible={isModalVisible} onCancel={cancel}>
    <AddTemplate modalStatus={'create'} bankId={this.state.currentId} onDataChange={() => this.getData()} onOk={() => cancel()}></AddTemplate>
</Modal>

2、子组件

  • currentData 作为可选传参数用 ?:表示
  • onDataChange:() => void 更新接口函数
  • onOk?: () => void 改变模态框函数
interface Props {
    currentData?: BankApproveDetailVo, 
    modalStatus: string, 
    bankId: number, 
    onDataChange: ()=>void, 
    onOk?: ()=>void
}

interface States {
    fields: any[],
    approveId: number,
    bankId: number
}

class AddTemplate extends Component<Props, States> {
    constructor(props: Props){
        super(props)
        this.state = {
            fields: [],
            approveId: this.props.currentData?.approveId || 0,
            bankId: this.props.bankId
        }
    }
    handleDefault = () => {
        const { approveId, bankId } = this.state;
        api.bankApproveIsDefault( approveId, bankId ).then((data: any) => {
            if(data.code === 200){
                message.success('设置默认模板成功')
                this.props.onDataChange()
            }else{
                message.error('设置默认模板失败')
            }
        })
    }
}

二、子-父通信

父组件获取子组件的值
  • 子组件在调用该函数时,就可以将想要交给父组件的数据以函数入参的形式给出去
1、父组件
class Father extends React.Component {
  // 初始化父组件的 state
  state = {
    text: "初始化的父组件的文本"
  };
  changeText = (newText) => {
    this.setState({
      text: newText
    });
  };
  // 渲染父组件
  render() {
    return (
      <div className="father">
        <p>{`父组件的文本内容是:[${this.state.text}]`}</p>
        <Child
          changeFatherText={this.changeText}
        />
      </div>
    );
  }
2、子组件
class Child extends React.Component {
  // 初始化子组件的 state
  state = {
    text: '子组件的文本'
  }

  // 子组件的按钮监听函数
  changeText = () => {
    this.props.changeFatherText(this.state.text)
  }
  render() {
    return (
      <div className="child">
        {/* 注意这里把修改父组件文本的动作放在了 Child 里 */}
        <button onClick={this.changeText}>
          点击更新父组件的文本
        </button>
      </div>
    );
  }
}
父组件调用子组件的方法
  • 通过ref将子组件将方法暴露给父组件
  • useImperativeHandle
父组件
const ref = useRef<any>();

ref.current?.onRefresh()

<CheckBoxComponent
    onRef={ref}
    listType='payment'
    onChangeChecked={handleChange}
    onSubmit={onSubmit}
    buttonText='确认关联'
    buttonVisible={Boolean(connectBtn)}
/>
子组件
interface Props {
    onRef?: React.Ref<any>
}

const CheckBoxItem: FC<Props> = (
    {
        onRef,
    }
) => {

    useImperativeHandle(onRef, () => {
        return {
            onRefresh() {
                refRecycler.current.refresh()
            }
        }
    }, [])
}

三、跨组件 context

  • Provider 是数据的发出者,Consumer 是数据的接收者
  • Provider 组件接受一个 value 属性,值可以是字符串也可以是对象等
  • Consumer 组件内可以通过 匿名函数的形式接收

新建 context.tsx 文件

import React from 'react';
const MyContext = React.createContext(null);
export { MyContext };

父组件

export const { Provider, Consumer } = React.createContext("默认值");

<MyContext.Provider value={name}>
    <Child />
</MyContextProvider>

子组件

import { MyConsumer } from './context'

<MyContext.Consumer>
  {(name) =>
      <div>
          <p>子组件:获取父组件的值:{name}</p>
          <Grand />
      </div>
  }
</MyContext.Consumer>

孙组件

import { MyConsumer } from './context'

<MyContext.Consumer>
  {
      (name) =>
          <div>
              <p>孙组件:获取父组件的值:{name}</p>
          </div>
  }
</MyContext.Consumer>

你可能感兴趣的:(React,TypeScript,前端开发,react,typescript)