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

Use insertion effect #77

Merged
merged 6 commits into from
Aug 8, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 40 additions & 40 deletions src/content/reference/react/useInsertionEffect.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ title: useInsertionEffect

<Pitfall>

`useInsertionEffect` is for CSS-in-JS library authors. Unless you are working on a CSS-in-JS library and need a place to inject the styles, you probably want [`useEffect`](/reference/react/useEffect) or [`useLayoutEffect`](/reference/react/useLayoutEffect) instead.
`useInsertionEffect` CSS-in-JS library author-দের জন্য। যদি না আপনি একটি কাজ করছেন এবং স্টাইল ইনজেক্ট করার জন্য একটা জায়গার প্রয়োজন বোধ করছেন, সম্ভবত আপনি `useInsertionEffect` এর বদলে [`useEffect`](/reference/react/useEffect) অথবা [`useLayoutEffect`](/reference/react/useLayoutEffect) ব্যবহার করতে চান।

</Pitfall>

<Intro>

`useInsertionEffect` allows inserting elements into the DOM before any layout effects fire.
`useInsertionEffect` কোন লেআউট effect fire করার আগেই DOM এ বিভিন্ন এলিমেন্ট ইন্সার্ট করার সুযোগ দেয়।

```js
useInsertionEffect(setup, dependencies?)
Expand All @@ -22,81 +22,81 @@ useInsertionEffect(setup, dependencies?)

---

## Reference {/*reference*/}
## রেফারেন্স {/*reference*/}

### `useInsertionEffect(setup, dependencies?)` {/*useinsertioneffect*/}

Call `useInsertionEffect` to insert styles before any effects fire that may need to read layout:
লেআউট রিড করতে হবে এমন কোন effect fire করার আগে স্টাইল ইনসার্ট করার জন্য `useInsertionEffect` কল করুনঃ

```js
import { useInsertionEffect } from 'react';

// Inside your CSS-in-JS library
// আপনার CSS-in-JS লাইব্রেরির মধ্যে
function useCSS(rule) {
useInsertionEffect(() => {
// ... inject <style> tags here ...
// ... <style> ট্যাগগুলো এখানে ইনজেক্ট করুন ...
});
return rule;
}
```

[See more examples below.](#usage)
[নিচে আরো উদাহরণ দেখুন।](#usage)

#### Parameters {/*parameters*/}
#### প্যারামিটার {/*parameters*/}

* `setup`: The function with your Effect's logic. Your setup function may also optionally return a *cleanup* function. When your component is added to the DOM, but before any layout effects fire, React will run your setup function. After every re-render with changed dependencies, React will first run the cleanup function (if you provided it) with the old values, and then run your setup function with the new values. When your component is removed from the DOM, React will run your cleanup function.
* `setup`: যেই ফাংশনে আপনার Effect এর লজিক আছে। আপনার সেটআপ ফাংশন একটি *cleanup* ফাংশন optionally রিটার্ন করতে পারে। আপনার কম্পোনেন্ট DOM এ যুক্ত হবার সময়, কিন্তু কোন লেআউট effect fire করার আগে, React আপনার সেটআপ ফাংশন রান করবে। পরিবর্তিত ডিপেন্ডেন্সির সাথে যতবার রি-রেন্ডার হবে, React প্রথমে আপনার পুরনো ভ্যালুগুলো ব্যবহার করে cleanup ফাংশন রান করবে (যদি আপনি দিয়ে থাকেন), তারপর নতুন ভ্যালুগুলো ব্যবহার করে সেটআপ ফাংশন রান করবে। আপনার কম্পোনেন্ট DOM থেকে সরিয়ে ফেলবার আগে, React আপনার cleanup ফাংশন রান করবে।

* **optional** `dependencies`: The list of all reactive values referenced inside of the `setup` code. Reactive values include props, state, and all the variables and functions declared directly inside your component body. If your linter is [configured for React](/learn/editor-setup#linting), it will verify that every reactive value is correctly specified as a dependency. The list of dependencies must have a constant number of items and be written inline like `[dep1, dep2, dep3]`. React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison algorithm. If you don't specify the dependencies at all, your Effect will re-run after every re-render of the component.
* **optional** `dependencies`: `setup` কোডের মধ্যে রেফারেন্স করা সকল রিয়াক্টিভ ভ্যালুর তালিকা। রিয়াক্টিভ ভ্যালুর মধ্যে রয়েছে props, state এবং আপনার কম্পোনেন্ট বডির মধ্যে সরাসরি ডিক্লেয়ার হওয়া সকল ভ্যারিয়েবল এবং ফাংশন। যদি আপনার লিন্টার [React এর জন্য কনফিগার করা থাকে](/learn/editor-setup#linting), এটা নিশ্চিত করবে যে প্রতিটা রিয়াক্টিভ ভ্যালু সঠিকভাবে ডিপেন্ডেন্সি হিসেবে চিহ্নিত করা আছে। ডিপেন্ডেন্সির তালিকাতে অবশ্যই আইটেমের সংখ্যা ধ্রুবক হতে হবে এবং `[dep1, dep2, dep3]` এর মত ইনলাইনে থাকতে হবে। React will compare each dependency with its previous value using the [`Object.is`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is) comparison algorithn ব্যবহার করে প্রতিটা ডিপেন্ডেন্সি এবং এর আগের ভ্যালু তুলনা করবে।আপনি যদি ডিপেন্ডেন্সি চিহ্নিত করে না দেন, আপনার Effect কম্পোনেন্টের প্রতিটি re-render এ re-run হবে।

#### Returns {/*returns*/}
#### রিটার্ন {/*returns*/}

`useInsertionEffect` returns `undefined`.
`useInsertionEffect` রিটার্ন করে `undefined`.

#### Caveats {/*caveats*/}
#### সতর্কতা {/*caveats*/}

* Effects only run on the client. They don't run during server rendering.
* You can't update state from inside `useInsertionEffect`.
* By the time `useInsertionEffect` runs, refs are not attached yet.
* `useInsertionEffect` may run either before or after the DOM has been updated. You shouldn't rely on the DOM being updated at any particular time.
* Unlike other types of Effects, which fire cleanup for every Effect and then setup for every Effect, `useInsertionEffect` will fire both cleanup and setup one component at a time. This results in an "interleaving" of the cleanup and setup functions.
* Effects শুধুমাত্র ক্লায়েন্টে কাজ করে। এগুলো সার্ভার রেন্ডারিং এর সময় রান করে না।
* আপনি `useInsertionEffect` এর মধ্য হতে state আপডেট করতে পারবেন না।
* যতক্ষণে `useInsertionEffect` রান করে, ref তখনো যুক্ত হয় নাই এবং DOM আপডেট হয় নাই।
* `useInsertionEffect` DOM আপডেটের আগেও রান করতে পারে, পরেও করতে পারে। কোন একটি নির্দিষ্ট সময়ে DOM আপডেট হবে এর উপর নির্ভর করে থাকবেন না।
* অন্যান্য Effect যেম্ন প্রতিবার ক্লিনআপ শুরু করে তার পর সেটাপ শুরু করে, `useInsertionEffect` তার ব্যতিক্রম। এটা প্রতিটি কম্পোনেন্টে একই সাথে ক্লিনাপ এবন সেটাপ শুরু করবে। যেটার ফলস্বরূপ, ক্লিনাপ এবং সেটাপ ফাংশনে একটা "interleaving" থেকে যায়।
---

## Usage {/*usage*/}
## ব্যবহার {/*usage*/}

### Injecting dynamic styles from CSS-in-JS libraries {/*injecting-dynamic-styles-from-css-in-js-libraries*/}
### CSS-in-JS লাইব্রেরিতে dynamic styles injection {/*injecting-dynamic-styles-from-css-in-js-libraries*/}

Traditionally, you would style React components using plain CSS.
প্রথাগতভাবে, আপনি React কম্পোনেন্ট plain CSS ব্যবহার করেই স্টাইল করবেন।

```js
// In your JS file:
// আপনার JS ফাইলেঃ
<button className="success" />

// In your CSS file:
// আপনার CSS ফাইলেঃ
.success { color: green; }
```

Some teams prefer to author styles directly in JavaScript code instead of writing CSS files. This usually requires using a CSS-in-JS library or a tool. There are three common approaches to CSS-in-JS:
কেউ কেউ আলাদা CSS ফাইলে স্টাইল করার কোড লেখার চেয়ে জাভাস্ক্রিপ্টে স্টাইল কোড লিখতে পছন্দ করেন। এতে সাধারণত কোন CSS-in-JS লাইব্রেরি বা কোন একটি টুল ব্যবহার করা প্রয়োজন পড়ে। CSS-in-JS ব্যবহারের তিনটি বহুল ব্যবহৃত পদ্ধতি আছেঃ

1. Static extraction to CSS files with a compiler
2. Inline styles, e.g. `<div style={{ opacity: 1 }}>`
3. Runtime injection of `<style>` tags
1. কম্পাইলার ব্যবহার করে CSS ফাইলে স্ট্যাটিক এক্সট্রাকশন
2. ইনলাইন স্টাইল, যেমন, `<div style={{ opacity: 1 }}>`
3. `<style>` ট্যাগের রানটাইম ইনজেকশন

If you use CSS-in-JS, we recommend a combination of the first two approaches (CSS files for static styles, inline styles for dynamic styles). **We don't recommend runtime `<style>` tag injection for two reasons:**
আপনি যদি CSS-in-JS ব্যবহার করেন, আমরা উপরের দুটি পদ্ধতির সমন্বয় ব্যবহার করতে উপদেশ দেব (স্ট্যাটিক স্টাইলের জন্য CSS ফাইল, ডাইনামিক স্টাইলের জন্য ইনলাইন স্টাইল।) **আমরা দুটি কারণে রানটাইম `<style>` ট্যাগ ইনজেকশন এড়িয়ে চলতে বলবঃ**

1. Runtime injection forces the browser to recalculate the styles a lot more often.
2. Runtime injection can be very slow if it happens at the wrong time in the React lifecycle.
1. রানটাইম ইনজেকশনের ক্ষেত্রে স্টাইলগুলোকে বার বার হিসেব করতে বাধ্য হয় ব্রাউজার।
2. React লাইফসাইকেলের ভুল একটা সময়ে যদি রানটাইম ইনজেকশন হয় তাহলে সেটা খুবই ধীরগতির হতে পারে।

The first problem is not solvable, but `useInsertionEffect` helps you solve the second problem.
প্রথম সমস্যাটা সমাধানযোগ্য নয়, কিন্তু `useInsertionEffect` আপনাকে দ্বিতীয় সমস্যাটা সমাধানে সাহায্য করবে।

Call `useInsertionEffect` to insert the styles before any layout effects fire:
কোন লেআউট effect fire করার আগে স্টাইল ইনসার্ট করার জন্য `useInsertionEffect` কল করুনঃ

```js {4-11}
// Inside your CSS-in-JS library
// আপনার CSS-in-JS লাইব্রেরির মধ্যে
let isInserted = new Set();
function useCSS(rule) {
useInsertionEffect(() => {
// As explained earlier, we don't recommend runtime injection of <style> tags.
// But if you have to do it, then it's important to do in useInsertionEffect.
// আগেই যেভাবে ব্যখ্যা করা হয়েছে, আমরা রানটাইমে <style> ট্যাগ ইনজেক্ট না করার পরামর্শ দেই।
// কিন্তু যদি আপনাকে এটা করতেই হয়, এটা useInsertionEffect এর মধ্যে করা জরুরি।
if (!isInserted.has(rule)) {
isInserted.add(rule);
document.head.appendChild(getStyleForRule(rule));
Expand All @@ -111,7 +111,7 @@ function Button() {
}
```

Similarly to `useEffect`, `useInsertionEffect` does not run on the server. If you need to collect which CSS rules have been used on the server, you can do it during rendering:
`useEffect` এর ন্যায়, `useInsertionEffect` সার্ভারে রান করে না। আপনার যদি সার্ভারে ব্যবহৃত CSS rule গুলো সংগ্রহ করার প্রয়োজন পড়ে, আপনি সেটা রেন্ডারিং এর সময়ে করতে পারেনঃ

```js {1,4-6}
let collectedRulesSet = new Set();
Expand All @@ -127,14 +127,14 @@ function useCSS(rule) {
}
```

[Read more about upgrading CSS-in-JS libraries with runtime injection to `useInsertionEffect`.](https://github.com/reactwg/react-18/discussions/110)
[CSS-in-JS libraries with runtime injection থেকে `useInsertionEffect` এ আপগ্রেড নিয়ে আরো পড়ুন।](https://github.com/reactwg/react-18/discussions/110)

<DeepDive>

#### How is this better than injecting styles during rendering or useLayoutEffect? {/*how-is-this-better-than-injecting-styles-during-rendering-or-uselayouteffect*/}
#### Rendering বা useLayoutEffect এর সময় স্টাইল ইঞ্জেক্ট করবার চেয়ে এটা কীভাবে আরো ভাল? {/*how-is-this-better-than-injecting-styles-during-rendering-or-uselayouteffect*/}

If you insert styles during rendering and React is processing a [non-blocking update,](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) the browser will recalculate the styles every single frame while rendering a component tree, which can be **extremely slow.**
আপনি যদি রেন্ডারিং এর সময় স্টাইল ইনসার্ট করেন যখন React একটি [নন-ব্লকিং আপডেট,](/reference/react/useTransition#marking-a-state-update-as-a-non-blocking-transition) প্রসেস করছে, ব্রাউজার একটি কম্পোনেন্ট ট্রি রেন্ডার করতে করতে প্রতিটা ফ্রেমে স্টাইলগুলো আবার হিসেব করে, যেটা **অত্যন্ত ধীরগতির হতে পারে।**

`useInsertionEffect` is better than inserting styles during [`useLayoutEffect`](/reference/react/useLayoutEffect) or [`useEffect`](/reference/react/useEffect) because it ensures that by the time other Effects run in your components, the `<style>` tags have already been inserted. Otherwise, layout calculations in regular Effects would be wrong due to outdated styles.
[`useLayoutEffect`](/reference/react/useLayoutEffect) বা [`useEffect`](/reference/react/useEffect) এর সময় স্টাইল ইনসার্ট করার চেয়ে `useInsertionEffect` ভাল, কারণ এটা নিশ্চিত করে যে যতক্ষণে আপনার কম্পোনেন্টে অন্যান্য Effect রান করছে, ততক্ষণে সকল `<style>` ট্যাগ ইনসার্ট করা হয়ে গেছে। অন্যথায়, পুরনো স্টাইলের কারণে সাধারণ Effect এ লেআউটের হিসেব ভুল হবে।

</DeepDive>
Loading