React/Redux/ReduxFormの構成でUIはMaterial-uiを使ってフォームを作成しています。
マルチセレクトのところで新規登録は問題ないのですが、一度登録した情報をGETで取得してから
セレクトで複数のユーザー名が表記されクリックしてチェックボックスをトグルで切り替え
して値(配列)の更新をしたいのですが、チェックボックスのon/offができません。
マルチセレクト:https://material-ui.com/demos/selects/#multiple-select
stateの流れですが、
(1) 親コンポーネントでGETした情報をpropsで渡し、子のコンポーネントで受け取ったpropsを
コピーしてSelectやCheckBoxの状態管理用の変数に代入してに初期化
(2) 初期化すると登録されてるユーザー名が表記され、changeイベントでチェックボックスをon/off切り替えて変更したいのですが、
配列の値がうまく更新されず、チェックも外れない状態になっています。
(3) 更新できたらチェックボックスの値をRedux-Formのprops.changeでformValueにセットしてpostする
問題はSelectとCheckBoxのそれぞれのコンポーネントで変数(selectedUser)の配列が同期されないので更新ができていないようです。
色々試してみましたが、期待通りの動きになりませんでした。
何か良い方法がありましたら、ご教授いただけると助かります。
■Parent.js(親) import React from 'react'; import { connect } from 'react-redux'; import { reduxForm } from 'redux-form'; import { withStyles } from '@material-ui/core/styles'; import ChildForm from '@/components/ChildForm'; const setInitial = apiData => { let initialValues = {}; Object.keys(apiData).forEach(key => { let value = apiData[key]; switch (key) { case 'multiple_select': let targetUserId = []; if (value && value.length > 0) { for (let val of value) { targetUserId.push(val.id); value = targetUserId; } } break; } initialValues[key] = value; }); return initialValues; }; class Parent extends React.Component { constructor(props) { super(props); } render() { const { initialValues } = this.props; const multipleOptions = [ { value: 1, label: 'A氏' }, { value: 2, label: 'B氏' }, { value: 3, label: 'C氏' } ]; return ( <div className={classes.root}> <ChildForm multiple_select={initialValues.multiple_select} multipleOptions={this.multipleOptions} /> </div> ); } } const mapStateToProps = state => { const getApiData = { multiple_select: [ { id: 1, name: 'A氏' }, { id: 2, name: 'B氏' }, { id: 3, name: 'C氏' } ] }; return { initialValues: setInitial(getApiData), multiple_form: state.form['multiple_form'] }; }; Parent = reduxForm({ form: multiple_form })(Parent); export default connect(mapStateToProps)(withStyles(styles)(Parent));
■ChildForm.js(子) import React from 'react'; import { connect } from 'react-redux'; import { reduxForm, reset } from 'redux-form'; import { withStyles } from '@material-ui/core/styles'; let selectedUser = []; → SelectやCheckboxの状態管理をするための変数 class ChildForm extends React.Component { constructor(props) { super(props); } // propsをコピーしてselectでユーザー名を表示させる componentWillReceiveProps() { if (this.props.multiple_select && this.props.multiple_select.length > 0) { selectedUser = [...this.props.multiple_select]; } } handleChangeSelect = event => { let getUser = event.target.value; selectedUser = [...getUser]; this.props.change([ { name: 'multiple_select', value: selectedUser } ]); }; render() { const { form, multiple_select, multipleOptions } = this.props; return ( <Paper> <FormControl> <InputLabel htmlFor="multiple-checkbox">マルチセレクト</InputLabel> <Select multiple displayEmpty value={selectedUser} onChange={this.handleChangeSelect} input={<Input id="multiple-checkbox" />} renderValue={selectedUser => { let selectedConvertName = []; if (selectedUser.length > 0) { for (let option of multipleOptions) { if (selectedUser.includes(option.value)) { selectedConvertName.push(option.label); } } } else { return '選択してください'; } return selectedConvertName.join('、 '); }} > {multipleOptions.map(option => { return ( <MenuItem key={option.value} value={option.value}> <Checkbox color="primary" checked={selectedUser.includes(option.value)} /> <ListItemText primary={option.label} /> </MenuItem> ); })} </Select> </FormControl> )} </Paper> ); } } const mapStateToProps = state => { return { multiple_form: state.form.multiple_form }; }; ChildForm = reduxForm({ form: state.form.multiple_form })(ChildForm); export default connect(mapStateToProps)(withStyles(styles)(ChildForm));

回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/05/10 01:24