redux-form(V7.4.2)笔记( 五)核心模块回顾
本系列文章学习和研究redux-form的主要参考资源,特别是代码部分,主要在于其官方网站提供的一切资源及工程源码剖析。 基础在使用 redux-form 之前,需要用户具备以下基础:
redux-form核心模块redux-form基于React-Redux状态管理理念,而form本身作为一种「特殊」的容器组件,要实现这种组件与数据中心(即Redux的store)的交互,关键在于把握 redux-form 的三个主要模块:
补充解释如下。 (一)关于redux-form的reducer有关代码如下(store.js): import { reducer as reduxFormReducer } from 'redux-form'; const rootReducer = combineReducers({ //other custom reducers form: reduxFormReducer,// mounted under "form" }); combineReducers工具函数组件各个子reducer,最后形成一个大型reducer,称为rootReducer。然后,以此rootReducer为参数传递给createStore创建Redux的store对象。 Reducer的作用是:负责根据子组件发出的Action和原有State生成新的State,即:
为了全面理解上面的代码,让我们再回顾一下Redux编程中Reducer拆分思想。Redux编程思想中建议把较大型的超过20行以上代码的reducer函数拆成了若干个小型的recducer函数,每一个负责生成对应的一部分state。而且,这种拆分与 React 应用的结构相吻合:一个 React 根组件由很多子组件构成。这就是说,子组件与子 Reducer 完全可以一一对应。 Redux 提供的combineReducers方法,正是用于 Reducer 的拆分。你只要定义各个子 Reducer 函数,然后用这个方法,即可将它们合并成一个大的 Reducer。 典型情况下,上述combineReducers方法用场是: 关于combineReducers方法还有一个重要细节,请注意如下代码: const rootReducer = combineReducers({ chatLogReducer,statusMessageReducer,userNameReducer,form: reduxFormReducer }); 这种写法有一个前提: State 的属性名必须与各个子 Reducer 同名;否则,就要采用下面的写法。 const rootReducer = combineReducers({ 将来使用上面代码的结果的方法是: 这一点在redux-form官方网站提供的实例InitializeFromStateForm中文件InitializeFromStateForm.js中即有如下使用方式: InitializeFromStateForm = connect( 上面代码行出现在示例表单定义模块的代码中,这里通过connect方法调用进一步包装表单组件,实现把store中state有关数据(state.accountReducer.data)映射到表单组件的属性上。 啰嗦上面这一些,就是为了强调一个简短的combineReducers调用意义重大,正是这一调用最终把store数据(代码中典型称为state)与组件props关联到一起。 (二)关于reduxForm()方法API部分的描述是:reduxForm(config:Object) 上面示例中的代码用法如下: InitializeFromStateForm = reduxForm({ form: 'initializeFromState',// a unique identifier for this form })(InitializeFromStateForm); InitializeFromStateForm = connect( state => ({ initialValues: state.accountReducer.data,// pull initial values from account reducer }),{ load: loadAccount },// bind account loading action creator )(InitializeFromStateForm); 上面reduxForm方法调用至少有两层含义: (1)此方法进一步封装上面定义的表单组件,从而实现组成表单的UI组件的属性(props)(包括表单具体定义中的各个内置属性与接下来通过connect创建的少数定制属性,例如load)与store中的数据(即state,这个state中的对应形式可能是对象也可能是函数)关联到一起。 (2)此方法返回一个新的表单组件,提供给index.js中ReactDOM.render方法最终渲染网页中的表单使用,有关代码如下: ReactDOM.render( <Provider store={store}> <div style={{ padding: 15 }}> <h2>Initialize From State</h2> <InitializeFromStateForm onSubmit={showResults} /> <Values form="initializeFromState" /> </div> </Provider>,rootEl ); (三)关于<Field/>组件所有需要与 store 数据连接的表单组件,都可以用 <Field/>。在正确使用它之前,需要清楚三条基本概念:
使用方法列举如下: 1.组件可以是任何自定义的 class 组件(如下面的MyCustomInput组件),或者其他第三方库。 /``` class MyCustomInput extends Component { 然后这样使用: import MyCustomInput from './MyCustomInput' //... <Field name="myField" component={MyCustomInput}/> ### 2.无状态组件 这是一个非常灵活的使用 <Field/> 的方法。你必须在你的 render() 方法外定义它,否则它每次渲染都会被重建,并且由于组件的 prop 会变,就会强制 <Field/> 进行渲染。如果你在 render() 内部定义无状态组件,不但会拖慢你的程序的运行,而且组件的input每次都会在组件重新渲染的时候失去焦点。 //在方法 render() 外定义 const renderField = (field) => ( <div className="input-row"> <input {...field.input} type="text"/> {field.meta.touched && field.meta.error && <span className="error">{field.meta.error}</span>} </div> ) //在render()方法内定义 <Field name="myField" component={renderField}/> ### 3.最简单且最常用的形式: input,select,or textarea 比如创建一个文字输入框组件 <Field component="input" type="text"/> # 参考 (1)https://github.com/tedyuen/react-redux-form-v6-example#field-value-lifecycle (2)http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_one_basic_usages.html (3)https://redux-form.com/7.4.2/docs/gettingstarted.md/ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |