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

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

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

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

Q&A

解決済

1回答

1376閲覧

React 関数を一つにまとめたい

whiwhdiw

総合スコア70

TypeScript

TypeScriptは、マイクロソフトによって開発された フリーでオープンソースのプログラミング言語です。 TypeScriptは、JavaScriptの構文の拡張であるので、既存の JavaScriptのコードにわずかな修正を加えれば動作します。

React.js

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

0グッド

0クリップ

投稿2020/03/03 11:52

編集2020/03/04 02:09

Changeイベントがはしった時に各CaseのChange関数が呼ばれるのですが
値を変更するstateが違うだけで処理内容は全く同じです。なので
onChangeという関数を作り、stateを引数で受け取り、その引数のstateを変えてあげるよう
な関数を作り、使いまわそうとしたのですが
Object literal may only specify known properties, and 't' does not exist in type 'SetStateAction<STate>'.tsというエラーが出てうまくいきません。

わかる人がいましたら教えて欲しいです

enum Type { On, Off, } interface STate { Case1: Type; Case2: Type; Case3: Type; } const Index:FC<Props> = () => { const [ state, setState ] = useState<STate> ({ Case1: ChangeType.Off Case2: CahngeType.Off Case3: CahngeType.Off Case4: CahngeType.Off }); // const onCase1Cahnge = () => { // state.Case1 === Type.On ? // setState({ ...state, Case1: Type.On }) // : setState({ ...state, Case1: Type.Off }) // } // const onCase2Cahnge = () => { // state.Case2 === Type.On ? // setState({ ...state, Case2: Type.On }) // : setState({ ...state, Case2: Type.Off }) // } // const onCase3ahnge = () => { // state.Case3 === Type.On ? // setState({ ...state, Case3: Type.On }) // : setState({ ...state, Case3: Type.Off }) // } // const onCase4ahnge = () => { // state.Case4 === Type.On ? // setState({ ...state, Case4: Type.On }) // : setState({ ...state, Case4: Type.Off }) // } const onChange = (t: STate) => { t === Type.On ? setState({ ...state.t: Type.On }) : setState({ ...state.t: Type.Off }) } }

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

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

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

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

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

hoshi-takanori

2020/03/03 23:23

やりたいことがよく分からないので、onChange を使う部分のコードも貼ってもらえませんか。
whiwhdiw

2020/03/04 02:10

onChangeのコードは一番下のです
whiwhdiw

2020/03/04 02:11

onCase1Cahnge、onCase2Cahnge、onCase3Cahnge、onCase4Cahngeの関数は中で使うstateが使うだけでやっている処理は同じなので一つの関数にまとめたいのです
guest

回答1

0

ベストアンサー

えっと、添削します。

TypeScript

1enum Type { 2 On, 3 Off, 4}

On と Off しかないものをわざわざ enum にする理由がわかりません。boolean でよいのでは。
また、3 種類以上ある場合も、TypeScript では enum よりも単なる値の列挙がいいという説もあります。
参考: [Typescript] enumよりもstring literalがイケてる - Qiita

TypeScript

1interface STate { 2 Case1: Type; 3 Case2: Type; 4 Case3: Type; 5} 6 7 8const Index:FC<Props> = () => { 9 const [ state, setState ] = useState<STate> ({ 10 Case1: ChangeType.Off 11 Case2: CahngeType.Off 12 Case3: CahngeType.Off 13 Case4: CahngeType.Off 14 });

React のクラスコンポーネントでは State を一つにまとめる必要がありましたが、React Hooks ではまとめる必要はありません。というか、特に理由がなければまとめないのが普通です。その方が効率が良いので。

(STate じゃなくて State では? とか、Type と CahngeType どっち? とか、useState の初期地に , が抜けてるとか、interface 定義では Case3 までしかない、とかは置いときます…。)

TypeScript

1// const onCase1Cahnge = () => { 2// state.Case1 === Type.On ? 3// setState({ ...state, Case1: Type.On }) 4// : setState({ ...state, Case1: Type.Off }) 5// }

これは例えば次のように使ってるってことですよね?(「使う部分のコード」を聞いたのはこういう意味です。)

TypeScript

1 return ( 2 <div> 3 <button onClick={onCase1Cahnge}>{state.Case1}</button> 4 <button onClick={onCase2Cahnge}>{state.Case2}</button> 5 <button onClick={onCase3Cahnge}>{state.Case3}</button> 6 </div> 7 );

でしたら、次のように書き換えられると思います。

TypeScript

1 const onChange = (key: keyof(STate)) => () => { 2 setState({ ...state, [key]: (state[key] === Type.On ? Type.Off : Type.On) }); 3 }; 4 5 return ( 6 <div> 7 <button onClick={onChange('Case1')}>{state.Case1}</button> 8 <button onClick={onChange('Case2')}>{state.Case2}</button> 9 <button onClick={onChange('Case3')}>{state.Case3}</button> 10 </div> 11 );

または、

TypeScript

1 const cases: (keyof(STate))[] = ['Case1', 'Case2', 'Case3']; 2 3 return ( 4 <div> 5 {cases.map(each => 6 <button key={each} onClick={onChange(each)}>{state[each]}</button> 7 )} 8 </div> 9 );

投稿2020/03/04 05:56

hoshi-takanori

総合スコア7895

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

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

whiwhdiw

2020/03/05 06:09

返信ありがとうございます。 そうですね。booleanでやりたいともおます。 buttonをeachで回しているのですがbutton自体は同じdiv要素で囲まれていなくデザインや配置も違います。 eachで回す以外に何か方法ってないのでしょうか?
whiwhdiw

2020/03/05 06:16

const onChange = (key: keyof(STate)) => () => { 上記の書き方なんですが) => () => { ってなんでアロー関数二回も使っているんですか?
hoshi-takanori

2020/03/05 06:31

onChange は関数を返す関数になってまして、onChange('Case1') は STate の Case1 の値をトグルする関数、onChange('Case2') は Case2 をトグルする関数、…を返します。いわゆるカリー化ってやつですね。 https://qiita.com/KtheS/items/1a93ba0a6d722a534439 「同じdiv要素で囲まれていなくデザインや配置も違う」のであれば map は使えませんし、state を一つにまとめる必要もない気がします。case ごとに useState して、onCase1Cahnge なども作らずに onClick に直接かけば良いのでは。 const [case1, setCase1] = useState(false); <button value={case1} onClick={() => setCase1(!case1)}>...</button>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問