React メモ

文字列プラス数字のidの正規表現

```js
const idRegex = /timePairId-\d/g
const result_id = timeAthtml.match(idRegex)
```

querySelectorAllで複数の同じidから値を取得

```js
    const Array = []
    const Selector = document.querySelectorAll('[id^=dateAndTimeAt__Item]')
    for (let i = 0; i < Selector.length; i++) {
      const target = Selector[i].innerHTML
      const result = target.match(正規表現)
      Array.push(String(result))
    }
```

querySelectorAllで複数の同じidから値を取得【連想配列】

```js
    const Array = []
    const Braces = {}
    const Selector = document.querySelectorAll('[id^=dateAndTimeAt__Item]')
    for (let i = 0; i < Selector.length; i++) {
      const target = Selector[i].innerHTML
      const result = target.match(正規表現)
      Array['name'] = result[0 + i]
      Array['email'] = result[1 + i]
      Array['pass'] = result[2 + i]
      Braces.push(Array)
    }
```

初回にuseEffectを使用したくない

```js
// useEffectを初回に使用したくないのでuseRefを使用
const isFirstRender = useRef(false)
// 初回だったらisFirstRenderにtrueを入れる
useEffect(() => {
  isFirstRender.current = true
}, [])
// useEffect
  useEffect(() => {
    if (isFirstRender.current) {
      isFirstRender.current = false
    } else {
    }
    })
```

React useEffect 複数の引数で発火させたい

```js
例
const [hasAaa, setAaa] = useState(0)
const [hasBbb, setBbb] = useState(0)
const [hasCcc, setCcc] = useState(0)
useEffect(() => {
  console.log("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@")
}, [hasAaa, hasBbb, hasCcc])
```

配列の要素の重複を調べる【JS】

```js
参考
前提
配列の中の要素は、「“”」の文字列要素である必要がある
const array = ["aaa", "bbb", "bbb", "ccc"]
const DuplicateCheck = array.filter(function (x, i, self) {
  return self.indexOf(x) !== self.lastIndexOf(x)
})
console.log(DuplicateCheck)
```

react useMemoでコンポーネントの再レンダリングをスキップ

```js
参考
import React, { useState, useMemo } from "react";
export default function App() {
  const [count1, setCount1] = useState(0);
  const [count2, setCount2] = useState(0);
  // 引数の数値を２倍にして返す。
  // 不要なループを実行しているため計算にかなりの時間がかかる。
  const double = count => {
    let i = 0;
    while (i < 1000000000) i++;
    return count * 2;
  };
  // count2 を２倍にした値をメモ化する。
  // 第２引数に count2 を渡しているため、count2 が更新された時だけ値が再計算される。
  // count1 が更新され、コンポーネントが再レンダリングされた時はメモ化した値を利用するため再計算されない。
  const doubledCount = useMemo(() => double(count2), [count2]);
  return (
    <>
      <h2>Increment(fast)</h2>
      <p>Counter: {count1}</p>
      <button onClick={() => setCount1(count1 + 1)}>Increment(fast)</button>
      <h2>Increment(slow)</h2>
      <p>
        Counter: {count2}, {doubledCount}
      </p>
      <button onClick={() => setCount2(count2 + 1)}>Increment(slow)</button>
    </>
  );
}
```

React 連想配列 受け取り

```js
const tasks = [
  { id: 1, title: "one" },
  { id: 2, title: "two" },
  { id: 3, title: "three" },
  { id: 4, title: "four" },
  { id: 5, title: "five" }
];
const list = tasks.map(task => {
  console.log(task.id)
  console.log(task.title)
});
```

React 連想配列 作成

```js
const Array = []
const Braces = {}
const xxxxxxxxx =  hasDateAndTimeAtItems.map(item => {
    Braces['date'] = item[0]
    Braces['startAt'] = item[1]
    Braces['endAt'] = item[2]
    Array.push(Braces)
    return (Array)
  })
console.log(xxxxxxxxx)
let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'
console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
```

React Map (連想配列) 作成

```js
      const associativeArrayConvert = hasDateAndTimeAtItems.map(item => {
        const itemMap = {
          date: item[0],
          startAt: item[1],
          endAt: item[2]
        }
        return itemMap
      })
console.log(associativeArrayConvert)
```

React Map (連想配列) 受け取り 取得 取り出し

```js
      associativeArrayConvert.map((item, index) => {
        console.log(item.startAt)
      });
```

キーと値のペアを作成し、ReactのsetStateする方法

```js
const [productQuantity, setProductQuantity] = useState({});
const handleQuantity = (e, id) => {
  setProductQuantity((currentQuantity) => ({
    ...currentQuantity,
    [id]: e.target.value,
  }));
};
```


Objectをコピーする （クローン）

```js
let user = {firstName: 'John', lastName: 'Doe' };
let user_clone = Object.assign({}, user);
```


Objectの2つの配列をmerge
https://stackoverflow.com/questions/7146217/merge-2-arrays-of-objects

```js
const mergeByProperty = (target, source, prop) => {
  source.forEach(sourceElement => {
    let targetElement = target.find(targetElement => {
      return sourceElement[prop] === targetElement[prop];
    })
    targetElement ? Object.assign(targetElement, sourceElement) : target.push(sourceElement);
  })
}
var target /* arr1 */ = [{name: "lang", value: "English"}, {name: "age", value: "18"}];
var source /* arr2 */ = [{name : "childs", value: '5'}, {name: "lang", value: "German"}];
mergeByProperty(target, source, 'name');
console.log(target)
```

配列 要素 削除 index 指定

https://stackoverflow.com/questions/5767325/how-can-i-remove-a-specific-item-from-an-array

```js
function removeItemOnce(arr, value) {
  var index = arr.indexOf(value);
  if (index > -1) {
    arr.splice(index, 1);
  }
  return arr;
}
console.log(removeItemOnce([2,5,9,1,5,8,5], 5))
[
  2,
  9,
  1,
  5,
  8,
  5
]
追加
var value = 3
var arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(function(item) {
    return item !== value
})
console.log(arr)
[ 1, 2, 4, 5 ]
```


配列 削除 特定の要素 指定
https://stackoverflow.com/questions/5767325/how-can-i-remove-a-specific-item-from-an-array

```js
function removeItemAll(arr, value) {
  var i = 0;
  while (i < arr.length) {
    if (arr[i] === value) {
      arr.splice(i, 1);
    } else {
      ++i;
    }
  }
  return arr;
}
console.log(removeItemAll([2,5,9,1,5,8,5], 5))
[
  2,
  9,
  1,
  8
]
追加
let value = 3
let arr = [1, 2, 3, 4, 5, 3]
arr = arr.filter(item => item !== value)
console.log(arr)
[ 1, 2, 4, 5 ]
```


stateをObjectで管理（追加、削除あり）

```js
https://stackblitz.com/edit/dynamic-input-fields-reactjs-kqbrx3?file=src%2FApp.js
import React, { useState } from "react";
function App() {
  const [inputList, setInputList] = useState([{ firstName: "", lastName: "" }]);
  // handle input change
  const handleInputChange = (e, index) => {
    console.log("e.target", e.target)
    const { name, value } = e.target;
    const list = [...inputList];
    list[index][name] = value;
    setInputList(list);
  };
  // handle click event of the Remove button
  const handleRemoveClick = index => {
    const list = [...inputList];
    list.splice(index, 1);
    setInputList(list);
  };
  // handle click event of the Add button
  const handleAddClick = () => {
    setInputList([...inputList, { firstName: "", lastName: "" }]);
  };
  return (
    <div className="App">
      <h3><a href="https://cluemediator.com">Clue Mediator</a></h3>
      {inputList.map((x, i) => {
        return (
          <div className="box">
            <input
              name="firstName"
              placeholder="Enter First Name"
              value={x.firstName}
              onChange={e => handleInputChange(e, i)}
            />
            <input
              className="ml10"
              name="lastName"
              placeholder="Enter Last Name"
              value={x.lastName}
              onChange={e => handleInputChange(e, i)}
            />
            <div className="btn-box">
              {inputList.length !== 1 && <button
                className="mr10"
                onClick={() => handleRemoveClick(i)}>Remove</button>}
              {inputList.length - 1 === i && <button onClick={handleAddClick}>Add</button>}
            </div>
          </div>
        );
      })}
      <div style={{ marginTop: 20 }}>{JSON.stringify(inputList)}</div>
    </div>
  );
}
export default App;
```

js 複数フォーム value 値 抽出

```js
  // 開始時間と終了時間のペアを取得
  function inputTimeAtExtraction(timePairId) {
    const inputTimePairAt = []
    // 同じtimePairIdをもつフォームから開始時間と終了時間の入力値を取得
    const timePairSelector = document.querySelectorAll(timePairId)
    for (let i = 0; i < timePairSelector.length; i++) {
      const timeAthtml = timePairSelector[i].innerHTML
      // 正規表現でinnerHTMLの中の時刻表記された箇所のみ抽出
      const timeAtRegex = /([01]?[0-9]|2[0-3]):([0-5][0-9])/
      const timeAtValue = timeAthtml.match(timeAtRegex)
      if (timeAtValue) {
        inputTimePairAt.push(timeAtValue[0])
      }
    }
    return inputTimePairAt
  }
```


重複 Object 取得 オフジェクト
https://qiita.com/masarufuruya/items/e0427364f35c3176d42b

```js
let objList = [{
  "id" : 5,
  "name" : "June"
},{
  "id" : 4,
  "name" : "Jane"
},{
  "id" : 3,
  "name" : "Julia"
},{
  "id" : 2,
  "name" : "Nancy"
},{
  "id" : 5,
  "name" : "June"
},{
  "id" : 5,
  "name" : "June"
}];
var uniqueUser = {};
objList.forEach(function(user) {
  if (!uniqueUser[user.id]) {
    uniqueUser[user.id] = user;
  }
});
console.log(uniqueUser)
```

重複した値 取得 抽出 JS
https://www.w3resource.com/javascript-exercises/javascript-array-exercise-20.php

```js
function find_duplicate_in_array(arra1) {
        var object = {};
        var result = [];
        arra1.forEach(function (item) {
          if(!object[item])
              object[item] = 0;
            object[item] += 1;
        })
        for (var prop in object) {
           if(object[prop] >= 2) {
               result.push(prop);
           }
        }
        return result;
    }
    console.log(find_duplicate_in_array([1, 2, -2, 4, 5, 4, 7, 8, 7, 7, 71, 3, 6]));
```

material ui マテリアル オーバーライド css カスタマイズ 修正

```js
https://material-ui.com/customization/globals/#cs#seminer
import { createMuiTheme, ThemeProvider } from '@material-ui/core/styles';
const theme = createMuiTheme({
  overrides: {
    // Style sheet name ⚛️
    MuiButton: {
      // Name of the rule
      text: {
        // Some CSS
        color: 'white',
      },
    },
  },
});
function DefaultProps() {
  return (
    <ThemeProvider theme={theme}>
      <Button>Change default props</Button>
    </ThemeProvider>
  );
}
```


配列のstateをjsonで表示する

```js
<div style={{ marginTop: 20 }}>{JSON.stringify(配列のstate)}</div>
```


## react-hook-form

複数のsubmitまたは、送信時に押したボタンによってvalueを変更したい場合

```js
import * as React from "react";
import { useForm } from "react-hook-form";

type FormInputs = {
  firstName: string
  lastName: string
}

const App = () => {
  const { register, handleSubmit, setValue } = useForm<FormInputs>();

  const onSubmit = (data: FormInputs) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName", { required: true })} />
      <input {...register("lastName", { required: true })} />
      <button onClick={() => setValue("firstName", "Bill")}>
        Set First Name Value
      </button>
      <button
        onClick={() =>
          setValue("lastName", "Luo", {
            shouldValidate: true,
            shouldDirty: true
          })
        }
      >
        Set Last Name
      </button>
      <input type="submit" />
    </form>
  );
};
```

https://react-hook-form.com/api/useform/setvalue