We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
<Loading ref={el => {this.el = el}} /> this.el.changeLoading(false); // 子组件某个方法
通过 props 解决数据共享问题,本质上是将数据获取的逻辑放到组件的公共父组件中。代码可能是这样的:
import React, { PureComponent } from 'react'; export default class App extends PureComponent { constructor(props) { super(props); this.state = { data: { sku: '', desc: '', }, }; } componentDidMount() { fetch('url', { id: this.props.id }) .then(resp => resp.json()) .then(data => this.setState({ data })); } render() { return ( <div> <ProductInfoOne data={this.state.data} /> <ProductInfoTwo data={this.state.data} /> </div> ); } } function ProductInfoOne({ data }) { const { sku } = data; return <div>{sku}</div>; } function ProductInfoTwo({ data }) { const { desc } = data; return <div>{desc}</div>; }
问题是随着嵌套的层次越来越深,数据需要从最外层一直传递到最里层,整个代码的可读性和维护性会变差。我们希望打破数据「层层传递」而子组件也能取到父辈组件中的数据。
React 16.3 的版本引入了新的 Context API,Context API 本身就是为了解决嵌套层次比较深的场景中数据传递的问题,看起来非常适合解决我们上面提到的问题。我们尝试使用 Context API 来解决我们的问题:
// context.js const ProductContext = React.createContext({ sku: '', desc: '', }); export default ProductContext; // App.js import React, { PureComponent } from 'react'; import ProductContext from './context'; const Provider = ProductContext.Provider; export default class App extends PureComponent { constructor(props) { super(props); this.state = { data: { sku: '', desc: '', }, }; } componentDidMount() { fetch('url', { id: this.props.id }) .then(resp => resp.json()) .then(data => this.setState({ data })); } render() { return ( <Provider value={this.state.data}> <ProductInfoOne /> <ProductInfoTwo /> </Provider> ); } } // ProductInfoOne.js import React, { PureComponent } from 'react'; import ProductContext from './context'; export default class ProductInfoOne extends PureComponent { static contextType = ProductContext; render() { const { sku } = this.context; return <div>{sku}</div>; } } // ProductInfoTwo.js import React, { PureComponent } from 'react'; import ProductContext from './context'; export default class ProductInfoTwo extends PureComponent { static contextType = ProductContext; render() { const { desc } = this.context; return <div>{desc}</div>; } }
// store.js import { createStore } from 'redux'; import reducer from './reducer'; const store = createStore(reducer); export default store; // reducer.js import * as actions from './actions'; import { combineReducers } from 'redux'; function ProductInfo(state = {}, action) { switch (action.type) { case actions.SET_SKU: { return { ...state, sku: action.sku }; } case actions.SET_DESC: { return { ...state, desc: action.desc }; } case actions.SET_DATA: { return { ...state, ...action.data }; } default: { return state; } } } const reducer = combineReducers({ ProductInfo, }); export default reducer; // action.js export const SET_SKU = 'SET_SKU'; export const SET_DESC = 'SET_DESC'; export const SET_DATA = 'SET_DATA'; export function setSku(sku) { return { type: SET_SKU, sku, }; } export function setDesc(desc) { return { type: SET_DESC, desc, }; } export function setData(data) { return { type: SET_DESC, data, }; } // App.js import React, { PureComponent } from 'react'; import { Provider } from 'react-redux'; import store from './store'; import * as actions from './actions'; class App extends PureComponent { componentDidMount() { fetch('url', { id: this.props.id }) .then(resp => resp.json()) .then(data => this.props.dispatch(actions.setData(data))); } render() { return ( <Provider store={store}> <ProductInfoOne /> <ProductInfoTwo /> </Provider> ); } } function mapStateToProps() { return { }; } function mapDispatchToProps(dispatch) { return { dispatch, }; } export default connect(mapStateToProps, mapDispatchToProps)(App); // ProductInfoOne.js import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; import * as actions from './actions'; class ProductInfoOne extends PureComponent { onEditSku = (sku) => { this.props.dispatch(actions.setSku(sku)); }; render() { const { sku } = this.props.data; return ( <div>{sku}</div> ); } } function mapStateToProps(state) { return { data: state.ProductInfo, }; } function mapDispatchToProps(dispatch) { return { dispatch, }; } export default connect(mapStateToProps, mapDispatchToProps)(ProductInfoOne); // ProductInfoTwo.js import React, { PureComponent } from 'react'; import { connect } from 'react-redux'; import * as actions from './actions'; class ProductInfoTwo extends PureComponent { onEditDesc = (desc) => { this.props.dispatch(actions.setDesc(desc)); }; render() { const { desc } = this.props.data; return ( <div>{desc}</div> ); } } function mapStateToProps(state) { return { data: state.ProductInfo, }; } function mapDispatchToProps(dispatch) { return { dispatch, }; } export default connect(mapStateToProps, mapDispatchToProps)(ProductInfoTwo);
Mobx 我理解的最大的好处是简单、直接,数据发生变化,那么界面就重新渲染,在 React 中使用时,我们甚至不需要关注 React 中的 state,我们看下用 MobX 怎么解决我们上面的问题
// store.js import { observable } from 'mobx'; const store = observable({ sku: '', desc: '', }); export default store; // App.js import React, { PureComponent } from 'react'; import store from './store.js'; export default class App extends PureComponent { componentDidMount() { fetch('url', { id: this.props.id }) .then(resp => resp.json()) .then(data => Object.assign(store, data)); } render() { return ( <div> <ProductInfoOne /> <ProductInfoTwo /> </div> ); } } // ProductInfoOne.js import React, { PureComponent } from 'react'; import { action } from 'mobx'; import { observer } from 'mobx-react'; import store from './store'; @observer class ProductInfoOne extends PureComponent { @action onEditSku = (sku) => { store.sku = sku; }; render() { const { sku } = store; return ( <div>{sku}</div> ); } } export default ProductInfoOne; // ProductInfoTwo.js import React, { PureComponent } from 'react'; import { action } from 'mobx'; import { observer } from 'mobx-react'; import store from './store'; @observer class ProductInfoTwo extends PureComponent { @action onEditDesc = (desc) => { store.desc = desc; }; render() { const { desc } = store; return ( <div>{desc}</div> ); } } export default ProductInfoTwo;
The text was updated successfully, but these errors were encountered:
No branches or pull requests
父组件内调用子组件方法
props 解决数据共享
通过 props 解决数据共享问题,本质上是将数据获取的逻辑放到组件的公共父组件中。代码可能是这样的:
问题是随着嵌套的层次越来越深,数据需要从最外层一直传递到最里层,整个代码的可读性和维护性会变差。我们希望打破数据「层层传递」而子组件也能取到父辈组件中的数据。
Context API
React 16.3 的版本引入了新的 Context API,Context API 本身就是为了解决嵌套层次比较深的场景中数据传递的问题,看起来非常适合解决我们上面提到的问题。我们尝试使用 Context API 来解决我们的问题:
Redux
Mobx
Mobx 我理解的最大的好处是简单、直接,数据发生变化,那么界面就重新渲染,在 React 中使用时,我们甚至不需要关注 React 中的 state,我们看下用 MobX 怎么解决我们上面的问题
GraphQL
The text was updated successfully, but these errors were encountered: