文章目录
- 1. props传递(父向子通信):
- 2. 回调函数作为props(子向父通信):
- 3. Context API:
- 4. Redux或MobX等状态管理库:
- 4.1 Redux使用示例
- 5. refs:
1. props传递(父向子通信):
- 说明: 父组件通过
props
属性向子组件传递数据。 - 如何进行: 在父组件中定义子组件时,通过属性名将值传给子组件,子组件通过
this.props
接收。
// 父组件
import ChildProps from "./ChildProps";
function ParentProps() {const message = "我是父组件";return <ChildProps message={message} />;
}export default ParentProps;// 子组件
function ChildProps(props: any) {return (<div><span>{props.message}</span><br /><span>我是子组件</span></div>);
}export default ChildProps;
2. 回调函数作为props(子向父通信):
- 说明: 子组件通过调用父组件传递的回调函数,将信息传回给父组件。
- 如何进行: 父组件定义一个方法,将其作为
prop
传递给子组件;子组件在适当的时候调用这个函数,传递数据或事件信息。
// 父组件
import ChildrenEmit from "./ChildrenEmit";
function ParentEmit() {const handleButtonClick = (value: string) => {console.log(value, "ParentEmit: handleButtonClick");};return (<div><ChildrenEmit onButtonClick={handleButtonClick}></ChildrenEmit></div>);
}export default ParentEmit;// 子组件
function ChildrenEmit (props: { onButtonClick: (arg0: string) => void; }) {return (<button onClick={() => props.onButtonClick('按钮被点击了~')}>点击</button>)
}export default ChildrenEmit;
3. Context API:
- 说明: 方式:
React
提供了一个Context API
,允许你在组件树中传递数据,而无需手动逐层传递props
。 - 如何使用:创建一个
Context
,使用React.createContext()
;在最顶层的组件中使用<MyContext.Provider value={value}>
包裹需要共享状态的组件树;在消费组件中使用<MyContext.Consumer>
或useContext(MyContext)
来访问上下文中的值。
// MyContext.ts
// 创建Context
import { createContext } from "react";export const MyContext = createContext('red');
// ParentContext.tsx
// 父组件
import { useContext } from "react";
import { MyContext } from "./MyContext";
import ChildrenContext from "./ChildrenContext";const ParentContext = () => {const contextValue = useContext(MyContext);return (<MyContext.Provider value={contextValue}><ChildrenContext /></MyContext.Provider>);
};export default ParentContext;
// ChildrenContext.tsx
// 子组件
import { useContext } from "react";
import { MyContext } from "./MyContext";
import GrandsonContext from "./GrandsonContext";const ChildrenContext = () => {const contentValue = useContext(MyContext);return (<div><div>子组件颜色: {contentValue}</div><GrandsonContext></GrandsonContext></div>);
};
export default ChildrenContext;
// GrandsonContext.tsx
// 孙组件
import { useContext } from "react";
import { MyContext } from "./MyContext";
import GranddaughterContext from "./GranddaughterContext";const GrandsonContext = () => {const contentValue = useContext(MyContext);return (<div><div>孙组件1颜色: {contentValue}</div><GranddaughterContext></GranddaughterContext></div>);
};export default GrandsonContext;
// GranddaughterContext.tsx
// 孙组件
import { useContext } from "react";
import { MyContext } from "./MyContext";const GranddaughterContext = () => {const contentValue = useContext(MyContext);return (<div><div>孙组件2颜色:{contentValue}</div></div>);
};export default GranddaughterContext;
4. Redux或MobX等状态管理库:
- 方式:适用于大型应用,通过将状态提升到一个单一的
store
中管理,任何组件都可以访问和修改store
中的状态。 - 如何使用:引入相应的库并设置
store
,使用Provider
组件将store
包裹在应用的最外层,组件内部通过connect
函数(Redux)
或Observer(MobX)
等与store
连接,从而获取或改变状态。
4.1 Redux使用示例
这个例子展示了如何创建一个简单的计数器应用,通过Redux管理状态。用户点击加减按钮时,会触发actions,然后通过reducer更新state,最终React组件根据新的state重新渲染。
- 安装
redux
和 和react-redux
库。
npm install redux react-redux
- 创建 Action
// actions.ts
export const increment = () => {return { type: 'INCREMENT' };};export const decrement = () => {return { type: 'DECREMENT' };};
- 创建
reducer
// reducer.ts
const initialState = { count: 0 };function counterReducer(state = initialState, action: { type: any; }) {switch (action.type) {case 'INCREMENT':return { ...state, count: state.count + 1 };case 'DECREMENT':return { ...state, count: state.count - 1 };default:return state;}
}export default counterReducer;
- 创建
store
// store.ts
import { createStore } from 'redux';
import counterReducer from './reducer';const store = createStore(counterReducer);export default store;
- 创建组件使用
import { connect } from 'react-redux';
import { increment, decrement } from './actions';
import { ReactElement, JSXElementConstructor, ReactNode, ReactPortal, MouseEventHandler } from 'react';function ParentRedux(props: { count: string | number | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | null | undefined; onIncrement: MouseEventHandler<HTMLButtonElement> | undefined; onDecrement: MouseEventHandler<HTMLButtonElement> | undefined; }) {return (<div><h1>Counter: {props.count}</h1><button onClick={props.onIncrement}>+</button><button onClick={props.onDecrement}>-</button></div>);
}const mapStateToProps = (state: { count: any; }) => ({count: state.count,
});const mapDispatchToProps = (dispatch: (arg0: { type: string; }) => any) => ({onIncrement: () => dispatch(increment()),onDecrement: () => dispatch(decrement()),
});export default connect(mapStateToProps, mapDispatchToProps)(ParentRedux);
- 根组件导入
import React from "react";
import "./App.css";
import { Provider } from 'react-redux';
import store from './page/redux/store';
import ParentProps from "./page/props/ParentProps";
import ParentEmit from "./page/emit/ParentEmit";
import ParentContext from "./page/context/ParentContext";
import ParentRefs from "./page/refs/ParentRefs";
import ParentRedux from "./page/redux/ParentRedux";function App() {return (<div className="App"><div className="App-item">测试父子传参:<ParentProps></ParentProps></div><div className="App-item">测试子传父:<ParentEmit></ParentEmit></div><div className="App-item">测试context传参:<ParentContext></ParentContext></div><div className="App-item">测试refs传参:<ParentRefs></ParentRefs></div><Provider store={store}><div className="App-item">测试redux传参:<ParentRedux></ParentRedux></div></Provider></div>);
}export default App;
这个例子展示了如何创建一个简单的计数器应用,通过
Redux
管理状态。用户点击加减按钮时,会触发actions
,然后通过reducer
更新state
,最终React
组件根据新的state
重新渲染。
5. refs:
- 方式:主要用于访问
DOM
元素或在组件之间传递一个可变的引用。 - 如何使用:可以通过
React.createRef()
创建ref
,然后将其附加到特定的React
元素上。在组件中,可以通过this.myRef.current
访问DOM
元素或在类组件间传递ref
以直接操作另一个组件的实例。
// ParentRefs.tsx
// 父组件
import { useRef } from "react";
import ChildRefs from "./ChildRefs";const ParentRefs = () => {const childRef = useRef<HTMLInputElement>(null);const handleClick = (): void => {childRef?.current?.focus();};return (<><ChildRefs ref={childRef} /><button onClick={handleClick}>Focus Child Input</button></>);
};export default ParentRefs;
// ChildRefs.tsx
// 子组件
import { forwardRef } from 'react';const ChildRefs = forwardRef<HTMLInputElement>((props, ref) => {return (<div><input type="text" ref={ref} /></div>);
});export default ChildRefs;