Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reactのエンドポイントの処理を書き換えて、連番でなくても重複が無ければ表示されるようにした #70

Merged
merged 3 commits into from Mar 23, 2023

Conversation

lef237
Copy link
Owner

@lef237 lef237 commented Mar 23, 2023

以前の状態では、必ずdivのidがhoge1から始まる連番になっている必要があり、Viewファイルを書くのが大変だった。

しかし、このPull Requestにより、divのIDの文字列が被っていなければ表示されるようになったので、一つのViewファイルで複数のReactコンポーネントを簡単に表示できるようになった。

具体的には、kaminariのようなgemを使うと、例えば1ページ目の表示数が10だとすると、.each.with_index(1)を使ったとしても、2ページ目のdivのidがhoge11から始まってしまい、そのページでは1からのスタートでは無くなってしまうため、Reactが表示されなくなってしまう恐れがあった。

今回の改善により、仮にhoge11から始まったとしても、問題なく表示されるようになった。重複が無く、なおかつエンドポイント側で指定された文字列が入っていればOKだからである。


※一点だけ注意点がある。

MountComponents(Hoge, "hoge", divElements);
MountComponents(Hogefuga, "hogefuga", divElements);

エンドポイントがこうなっていたとき、hogefugaというidがあると、後者のHogefugaが使われる。
(順番を逆にすると、Hogeのほうが使われてしまう)

そのため、hogefugaの中にhogefugaが使われている場合には、先にhogefugaを含むコンポーネントを書いてあげよう。

OKな例

MountComponents(Hoge, "hoge", divElements);
MountComponents(Fuga, "fuga", divElements);
MountComponents(Hogefuga, "hogefuga", divElements);

頭の中で(ベン図のような)数学的な集合をイメージすれば、これなら問題ないと分かるはずである。
なぜなら、hogefugaを満たすためには、必要十分条件を満たす必要があるからだ。

NGな例

MountComponents(Hogefuga, "hogefuga", divElements);
MountComponents(Hoge, "hoge", divElements);
MountComponents(Fuga, "fuga", divElements);

この場合、hogefugaFugaでマウントされてしまう。

@@ -5,14 +5,19 @@ import Mount from "./Mount";
const MountComponents = (
component: unknown,
divName: string,
numberOfComponents: number
divElements: NodeListOf<HTMLDivElement>
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

カーソルを当てると型が分かる場合がある

}
}

const divNames = Array.from(elements).map((div) => div.id);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array.from()を使用して、HTMLDivElement[]を配列に変換している。そして、Array.prototype.map()を使用して、各要素のidプロパティを文字列に変換し、divNamesへと格納している。

MountComponents(Hey, "hey", divElements);
MountComponents(Hola, "hola", divElements);
// holaholaをHelloでマウントしている。実験的な例。
MountComponents(Hello, "holahola", divElements);
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

必要十分条件の実験。コード上のこの順番なら大丈夫。

下のコードは悪い例。

MountComponents(Hello, "holahola", divElements);
MountComponents(Hola, "hola", divElements);

この場合はholaholaと書いていても、Holaのほうでマウントされてしまうのでバグを生む可能性がある。

@lef237 lef237 merged commit cd183a5 into main Mar 23, 2023
2 checks passed
@lef237
Copy link
Owner Author

lef237 commented Mar 23, 2023

補足:名前に重複があると、次のようなwarningメッセージが出る。(マウントの文字列にhogeとhogefugaがあって、hogeが被っている場合など)

image

application-fa69c02.js:3003 Warning: You are calling ReactDOMClient.createRoot() on a container that has already been passed to createRoot() before. Instead, call root.render() on the existing root instead if you want to update it.

@lef237 lef237 deleted the super-react-render-solution branch September 22, 2023 10:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant