質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

2600閲覧

redux toolkit を使って 入力欄の追加ボタンを実装したい

07290729

総合スコア15

Redux

Reduxは、JavaScriptアプリケーションの状態を管理するためのオープンソースライブラリです。ReactやAngularで一般的にユーザーインターフェイスの構築に利用されます。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

1クリップ

投稿2020/07/29 03:10

編集2020/07/29 04:48

react + redux toolkit にて入力欄の追加ボタンを実装しようとしているのですが
ローカル関数での配列操作をうまくstateに反映できていないようで
ボタンを押しても入力欄がうまく追加されません。。。

以下のようなコードなのですが
"+" ボタンを押しても何も反応せずでして・・・
(consoleを見る限り、ローカル関数内の配列は無事に追加できているようなのですが、、)

原因と修正方法お分かりの方いらっしゃいましたら
ご教授お願いします。。。

index.js

1import React from "react"; 2import './index.css'; 3import ReactDOM from "react-dom"; 4import App from "./App"; 5import { Provider } from "react-redux"; 6//import { setupStore } from "./store"; 7import * as serviceWorker from './serviceWorker'; 8import { store } from './store'; 9 10//const store = setupStore(); 11 12ReactDOM.render( 13 <Provider store={store}> 14 <App /> 15 </Provider>, 16 document.getElementById("root") 17); 18 19// If you want your app to work offline and load faster, you can change 20// unregister() to register() below. Note this comes with some pitfalls. 21// Learn more about service workers: https://bit.ly/CRA-PWA 22serviceWorker.unregister();
import React from "react" import { useDispatch, useSelector } from "react-redux" import { useForm } from 'react-hook-form' import { setAddresses } from './rootSlice' import './common.css' const App = () => { const dispatch = useDispatch(); const Addresses = useSelector(state => state.Addresses) const { register, handleSubmit } = useForm(); const addresses = ["address0"] const onSubmit = (data) => { dispatch(setAddresses(data.addresses)) } const addAddress = () => { addresses.push(`address${addresses.length}`) console.log("addresses: ", addresses) } return ( <form onSubmit={handleSubmit(onSubmit)}> <div className="div-block"> {Addresses.map((address, index) => { return ( <> <label>Address {index}</label> <input name={`addresses[${index}]`} ref={register} /> </> ) })} <button type="button" onClick={addAddress}>+</button> <button type="submit" className="btn-square-shadow">Apply !</button> </div> <div> <hr></hr> {Addresses.map((address, index) => { return ( <> <div>Address {index}: {address}</div> </> ) })} </div> </form> ); }; export default App;
import { createSlice } from '@reduxjs/toolkit' const rootSlice = createSlice({ name: "address", initialState: { Name: "XXXX", Addresses: ["hoge-1-1-1"] }, reducers: { setName: (state, action) => { state.Name = action.payload }, setAddresses: (state, action) => { state.Addresses = action.payload }, } }) export const reducer = rootSlice.reducer; export const { setName, setAddresses, addAddresses } = rootSlice.actions
import { configureStore } from '@reduxjs/toolkit' import { reducer } from './rootSlice' export const store = configureStore({ reducer })

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

rootSlice.jsとApp.jsを以下のようなコードに変えたところ
自己解決しました。

1 import { createSlice } from '@reduxjs/toolkit' 2 3 const rootSlice = createSlice({ 4 name: "address", 5 initialState: { 6 Addresses: [""] 7 }, 8 reducers: { 9 setAddresses: (state, action) => { state.Addresses = action.payload }, 10 addAddresses: (state, action) => { state.Addresses.push(action.payload) }, 11 } 12 }) 13 14 export const reducer = rootSlice.reducer; 15 16 export const { setAddresses, addAddresses } = rootSlice.actions
import React from "react" import { useDispatch, useSelector } from "react-redux" import { useForm } from 'react-hook-form' import { setAddresses, addAddresses } from './rootSlice' import './common.css' const App = () => { const dispatch = useDispatch(); const Addresses = useSelector(state => state.Addresses) const { register, handleSubmit } = useForm(); const addresses = ["address0"] const onSubmit = (data) => { dispatch(setAddresses(data.addresses)) } const addAddress = () => { addresses.push(`address${addresses.length}`) dispatch(addAddresses("")) } return ( <form onSubmit={handleSubmit(onSubmit)}> <div className="div-block"> {Addresses.map((address, index) => { return ( <> <label>Address {index}</label> <input name={`addresses[${index}]`} ref={register} /> </> ) })} <button type="button" onClick={addAddress}>+</button> <button type="submit" className="btn-square-shadow">Apply !</button> </div> <div> <hr></hr> {Addresses.map((address, index) => { console.log("Name: ", address) return ( <> <div>Address {index}: {address}</div> </> ) })} </div> </form> ); }; export default App;

投稿2020/07/30 21:17

07290729

総合スコア15

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

redux-toolkit は関係ありません。
React ではコンポーネントの state と props 以外の変数が変更されても描画の結果は変化しません。
React コンポーネントに状態を持たせるには state を使う必要があります。
コンポーネントの state が適切な方法で更新されるとそのコンポーネントは再描画されます。
関数コンポーネントであれば次のようにしてコンポーネントの状態を定義します。

js

1const [addresses, setAddresses] = React.useState(['address0']); 2... 3 4setAddresses(`address${addresses.length}`);

React の基本的なことなのでチュートリアルの概要を読み直すことをおすすめします。:
https://ja.reactjs.org/tutorial/tutorial.html#overview

投稿2020/07/30 08:03

og24715

総合スコア832

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

07290729

2020/07/30 08:59

og24715さん ご回答ありがとうございます。 おっしゃるようなuseStateを用いたコードはすでに以下で作成済みです。 https://teratail.com/questions/267504 ただ本件では複数のコンポーネントで親子孫の関係になっているコード群で 状態管理と結果としての描画が最終ゴールなのですが useStateではstate更新→renderが再renderの限界エラーになってしまい断念しました。 ※<input name="hoge" /> などの単一の値であれば不要ですが  hoge1, hoge2, hoge3,,,, などの同じ種類の異なる値群を扱おうとしたときに  なんらかの形でこの状態を保持しようとしたところ複数の親子関係でstate更新→再renderが発生し  このエラーとなりました。。。 (このエラー発生したコードについては業務で書いているコードに直接関連するもので すぐには具体的なコードをここにあげられない状態です。。。申し訳ありません) そこで状態管理方法を一から構築しなおし その過程で状態管理のコードをシンプルに書けるredux toolkitを導入した次第です。 "state と props 以外の変数の変更"で再renderを防ぎ 追加ボタンを押すことなどの具体的なアクションで stateに反映→再renderというロジックを想定しています。
og24715

2020/07/30 09:46

?テキストフィールドをリアルタイムでコンポーネント state ではなく、Redux で管理したいってことですか
07290729

2020/07/30 10:06

私の知識がとぼしく、内容を正確にとらえられているか自信はないですが おそらくおっしゃられている内容どおりです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問