MENU

HTML 入れ子構造 小要素がはみ出すケース

小要素が親の要素をはみ出すケース

レイアウトを担うdivタグでは 上手くレイアウト組めているのに入れ子構造になると 小要素がはみ出す件

事象は青枠が親のグレーのボーダーををはみ出す 構造的にaクラスがアル場合に右側の要素と被ってしまう

  • html
<div class="parent">
  <div class="container">
    <div class="a">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
  </div>

  <div class="container">
    <div class="a">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
  </div>
</div>

.parent {
  display: flex;
}

.container {
  border: 1px solid gray;
  width: 200px;
  display: flex;
  flex-direction: row;
}

.box1 {
  border: 1px solid red;
  width: 100px;
  height: 50px;
}

.box2 {
  box-sizing: content-box;
  border: 1px solid blue;
  width: 100px;
  height: 50px;
  margin: 0 10px; 
}

.a {
    display: flex;
  flex-direction: row;
}


/* box-sizing: border-box; */

クラスaがない場合はいい感じに収まる

  • htmlはこれ
<div class="parent">
  <div class="container">
      <div class="box1"></div>
      <div class="box2"></div>
  </div>

  <div class="container">
    <div class="a">
      <div class="box1"></div>
      <div class="box2"></div>
    </div>
  </div>
</div>

対策方法

構造を変えるしかない 親要素と孫要素の関係は連動しない点を考えて構造を作成するしかないっぽい

React開発で知っておくと開発が楽になる書き方 まとめ

スプレット演算子

新しいオブジェクトや配列を複製するときや、更新する時に便利

## 更新
const params = {
  complete_date: { start: 'aa', end: 'bb'},
  due_date: { start: 'aa', end: 'bb'}
}

const newParams = {...params, complete_date: { start: 'cc', end: 'dd' }}

console.log(newParams)
  • 一括更新をしたい場合

キーが同じであれば一括更新可能

const obj = {id: 1, name: "aa", data: "data1"}

const obj2 = {id: 1, name: "aa22", data: "data222"}

const newObj = { ...obj, ...obj2 }

console.log(newObj)

=> {
  data: "data222",
  id: 1,
  name: "aa22"
}


### ...がないと
const newObj = { ...obj, obj2 }

=> {
  data: "data1",
  id: 1,
  name: "aa",
  obj2: [object Object] {
    data: "data222",
    id: 1,
    name: "aa22"
  }
}
  • 配列のデータの中の要素を更新する場合
const obj2 = {id: 2, name: "aa22", data: "data222"}

const arrs = [
  {id: 1, name: "aa", data: "data1"},
  {id: 2, name: "bb", data: "data2"},
]


const newAer = arrs.map((item) => {
  if (item.id === obj2.id) {
    return { ...item, ...obj2 }
  } else {
    return item
  }
})


console.log(newAer)

オブジェクトの更新 キー利用

キーを利用した方がコードを簡潔にかける時があった

  • キーを利用しない方法
const params = {
  complete_date: { start: 'aa', end: 'bb'},
  due_date: { start: 'aa', end: 'bb'}
}

params.complete_date.start = 'cc'
params.complete_date.end = 'dd'
console.log(params)
  • キーを利用する方法
const params = {
  complete_date: { start: 'aa', end: 'bb'},
  due_date: { start: 'aa', end: 'bb'}
}

params['complete_date'] = { start: 'cc', end: 'dd'}
console.log(params)

React setState レンダリング メモ

setSateの理解の重要性

  • stateを更新すると再レンダリングが走る
  • レンダリングが走ると、マウント、update(ライフサイクル)が走る
  • useEffect内の処理が走るためその中にデータ取得の処理があればロジックの理解に大切

setState

  • 丁寧な書き方

setStateは setState(updater[, callback]) となっている 丁寧に書くと下記の様になる見たい

## 簡略化
setState({counter: counter += 1})

## 丁寧な書き方
this.setState((state, props) => {
  return {counter: state.counter + props.step};
});
  • 非同期

setStateは非同期処理っぽいので setStateで値を更新してすぐにstateを利用すると値がセットされないことがある 実際に自分でも体験したのは下記

badの方法でAPIリクエストしたら valが渡されいなかった。 おそらくstate更新の非同期処理のせいなんだと思う

### bad
const updateValue = (val: number) => {
  setValue({value: val})

  ## apiを実行する関数です
  updateValue(value)
}

### good

const updateValue = (val: number) => {
  setValue({value: val})

  ## apiを実行する関数です
  updateValue(val)
}

補足情報

  • ライフサイクル

zenn.dev

Extract Typescript 便利な型

Extractとは?

リテラル型で一部だけ利用したい場合に利用できるみたい

下記の様なリテラル型があったとする

type KeySelect = 'user_type' | 'user_id' | 'start_date' | 'end_date';

どの中で、user_typeとuser_idだけ利用したい場合下記で型づけが可能

Extract<KeySelect, 'user_type' | 'user_id' >

これ結構便利だった

Redis 管理方法

Rrdisの状態確認を確認する方法を学ぶ

以前別の記事を作成して、Redisでバックグランド処理を実行する流れを検証していたけど、 実際に動いているのか確認したかったの方法を調べた

blog.hatena.ne.jp

結論

  • cliコマンドを利用して確認する

cliコマンド

qiita.com

こちらを参考に

ただ状態を確認するコマンドは特になかったかな?

下記のコマンドでキューの数を確認できるのでそれで実行完了したか判断するしかなさそうだった

redis-cli LLEN task_queue

React における clearIntervalの利用の理解

内容

clearIntervalが何をしているのかわからなかった

結論

  • 別画面に行く時にsetIntervalをクリアしてくれる

コード

これは6秒ごとに triggerGetData関数を実行していて、 別画面に行く時、つまりコンポーネントがアンマウントされた時に、 clearIntervalしてくれる

これがないと別画面に行ってもtriggerGetData関数が実行されるんだろうな triggerGetData関数はAPIを叩いているのでこれがないと不要なリクエストが溜まっていくんだろうな

useEffect(() => {
    triggerGetData();
    const _intervalId = setInterval(() => {
      triggerGetData();
    }, 6000);

    return () => {
      clearInterval(_intervalId);
    };
  }, []);

Redis バックグラウンド処理をする仕組みを理解する

知りたかったこと

  • Redisを活用したバックグラウンド処理の管理

結論

下記のフローを理解してると良さそう

  • キューにタスクを追加 (lpush):
  • バックグラウンドプロセスでタスクをポーリング:
  • タスクを処理する関数を呼び出す

また、Redisの基本的な特徴も把握しておくと良い

  • RedisはNoSQLデータベース
  • インメモリ型
  • シングルスレッドで、並列処理をする場合はシャーディング(複数Redis立ち上げる)

背景

  • 今仕事で開発中のタスクで処理が重たいので、バックグラウンド処理を行うようにしている。ただ、ローカル環境でのデバックが難しかったので、しっかり理解しようと思った

サンプルコード

ChatGPTが教えてくれたコード

project-folder/
├── docker-compose.yml
└── app/
    ├── package.json
    ├── app.js
  • docker-compose
version: '3'
services:
  redis:
    image: "redis:latest"
    ports:
      - "6379:6379"

バージョンが4系だと以降に記載するコードは動かない

{
  "dependencies": {
    "redis": "^3.1.2"
  }
}
  • app.js
const redis = require('redis');

// Redisクライアントの作成
const client = redis.createClient({ host: 'localhost' }); // Docker Composeのサービス名


const someProcess = () => {
  for (  var i = 0;  i < 10;  i++  ) {
    console.log(i)
  }
}

// タスクのスケジューリング
const scheduleTask = (taskData) => {
  const taskID = `task:${taskData.id}`;
  client.hmset(taskID, taskData);
  client.lpush('task_queue', taskID);
};

// タスクの処理
const processTask = (taskID) => {
  client.hgetall(taskID, (err, taskData) => {
    if (err) throw err;
    console.log('Processing task:', taskData);
    someProcess()
    setTimeout(() => {
      const result = 'Task completed successfully';
      client.set(`task_result:${taskID}`, result);
      console.log('Task completed:', result);
    }, 3000); // 3秒間のタスクをシミュレート
  });
};

// タスクを処理するループ
const processTasksLoop = () => {
  client.rpop('task_queue', (err, taskID) => {
    if (err) throw err;
    if (taskID) {
      console.log(`taskID ${taskID}`)
      processTask(taskID);
    }
    setTimeout(processTasksLoop, 1000); // 新しいタスクを待つ
  });
};

// テスト用タスクのスケジューリング
scheduleTask({ id: 'task123', param1: 'value1', param2: 'value2' });
scheduleTask({ id: 'task234', param1: 'value2', param2: 'value3' });
scheduleTask({ id: 'task567', param1: 'value3', param2: 'value4' });

// タスクの処理を開始
processTasksLoop();
  • 実行結果

ポーリングされる時に関数を挟むと実行できるだな

taskID task:task123
Processing task: { id: 'task123', param1: 'value1', param2: 'value2' }
0
1
2
3
4
5
6
7
8
9
taskID task:task234
Processing task: { id: 'task234', param1: 'value2', param2: 'value3' }
0
1
2
3
4
5
6
7
8
9
taskID task:task567
Processing task: { id: 'task567', param1: 'value3', param2: 'value4' }
0
1
2
3
4
5
6
7
8
9
Task completed: Task completed successfully
Task completed: Task completed successfully
Task completed: Task completed successfully

Redisのメソッド

  • client.set

キューに対して、データをセットするメソッド

  • client.hmset(今は非推奨)

ハッシュ(Hash)としてデータを設定するメソッド

  • client.lpush

リスト(List)に値を追加z

調べた内容

Redisとは

qiita.com

この記事によると

  • データベース
  • インメモリキャッシュなのが味噌っぽい
  • NoSQL
  • NoSQLだが扱える型は決まっているっぽい
  • シングルスレッド: 複数のリクエストが来ても、順番に処理される
  • シャーディング可能

気になった点

  • データベースなのになんで Mysqlとかと同じ感じで出てこないのか?

自分で結論づけたのは、インメモリキャッシュだから、サーバーが落ちると消えるのでMysqlなどとは同じ扱いにならないのではないか?と思った

  • シングルスレッドについて

Redisって重い処理をバックグランド処理に使われているイメージなんだけど、 シングルスレッドで実行されているので、都合悪いケースが多いのではないか? と思った。

そこは、マルチスレッドではなく、シャーディングという方法があるらしく、 複数台のredisサーバーを立てて、分散させるっぽい

複数台のサーバーの管理で肝になるのが 「slot」で、idnのようなもので管理している