react需要通信的情况,可以简单归类为:
1.父子之间
2.跨组件
3.跨react框架
1.一步到位的解决办法:events
events 在vue react angular甚至JQ里都能用到,
原理就是提交事件,监听事件.
维护的话,现在的IDE软件搜索事件名反应很快
安装:
npm install events --save
在项目入口或者utils建一个events.js
import { EventEmitter } from 'events';
export default new EventEmitter();
发送事件
比如子组件
import emitter from '@/utils/event.js';
const TopTitle = ({ count }) => {
const handleMenuChange = useCallback((list, obj) => {
emitter.emit('bindSelectChange', objParams);
}, []);
return (
<SectionHead>
<div className="left_wrap">
<div className="left_title">XXX</div>
<div className="left_num">{count}</div>
</div>
<div className="right_wrap">
<div onChange={handleMenuChange} ></div>
</div>
</SectionHead>
);
};
接收事件
useEffect(() => {
emitter.addListener('bindSelectChange', (data) => {
//console.log(data);
setBidParams(data);
});
},]);
2.父子通信
这个基本大家都会哈,大概思路是父组件传递一个函数给子组件,子组件在需要的时候调用这个父组件
父组件
const TendAndBid = ({ data, countNumber,onSelectChange }) => {
return (
<BidWrapper>
<TopTitle count={countNumber} onSelect={onSelectChange}></TopTitle>
<DownList item={data} ></DownList>
</BidWrapper>
);
};
子组件
const [objParams, setObjParams] = useState(null);
const handleMenuChange = useCallback((list, obj) => {
setObjParams(() => {
return obj_params;
});
}, []);
//子到父组件通信
useEffect(() => {
if (objParams) {
onSelect(objParams)
}
}, [objParams]);
return (
<SectionHead>
<div className="left_wrap">
<div className="left_title">XXX</div>
<div className="left_num">{count}</div>
</div>
<div className="right_wrap">
<Menu menuConfig={menuConfig} onChange={handleMenuChange} />
</div>
</SectionHead>
);
3.跨父子通信
react hook 推荐的是useContext
比如爷孙组件通信,使用流程大致是
a.在爷爷组件创建一个context标签并初始化值,暴露出去
const ThemeContext = React.createContext(themes.light);
b.父组件引用爷爷组件,然后用标签包裹住要通信的组件的入口
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
c.孙子组件通过useContext拿到该值
import { ThemeContext} from xxx
const theme = useContext(ThemeContext);
总的来说context必须通过createContext先造,提供给下层,下层才能通过useContext拿到
附上官网完整例子
const themes = {
light: {
foreground: "#000000",
background: "#eeeeee"
},
dark: {
foreground: "#ffffff",
background: "#222222"
}
};
const ThemeContext = React.createContext(themes.light);
function App() {
return (
<ThemeContext.Provider value={themes.dark}>
<Toolbar />
</ThemeContext.Provider>
);
}
function Toolbar(props) {
return (
<div>
<ThemedButton />
</div>
);
}
function ThemedButton() {
const theme = useContext(ThemeContext);
return (
<button style={{ background: theme.background, color: theme.foreground }}>
I am styled by theme context!
</button>
);
}
网友评论