From 75a259881d3b3c241ddd12bc9c299a40aefaa047 Mon Sep 17 00:00:00 2001 From: Sophie Alpert Date: Fri, 1 Mar 2019 17:27:47 -0800 Subject: [PATCH 001/152] Update tutorial.md --- content/tutorial/tutorial.md | 64 +++++++++++++----------------------- 1 file changed, 22 insertions(+), 42 deletions(-) diff --git a/content/tutorial/tutorial.md b/content/tutorial/tutorial.md index 9e1e58872..1c69ae99f 100644 --- a/content/tutorial/tutorial.md +++ b/content/tutorial/tutorial.md @@ -31,8 +31,6 @@ The tutorial is divided into several sections: You don't have to complete all of the sections at once to get the value out of this tutorial. Try to get as far as you can -- even if it's one or two sections. -It's fine to copy and paste code as you're following along the tutorial, but we recommend to type it by hand. This will help you develop a muscle memory and a stronger understanding. - ### What Are We Building? {#what-are-we-building} In this tutorial, we'll show how to build an interactive tic-tac-toe game with React. @@ -188,7 +186,9 @@ The Square component renders a single ` + + + ); +} +``` + +If you first click "Show alert" and then increment the counter, the alert will show the `count` variable **at the time you clicked the "Show alert" button**. This prevents bugs caused by the code assuming props and state don't change. + +If you intentionally want to read the *latest* state from some asynchronous callback, you could keep it in [a ref](/docs/hooks-faq.html#is-there-something-like-instance-variables), mutate it, and read from it. + +Finally, another possible reason you're seeing stale props or state is if you use the "dependency array" optimization but didn't correctly specify all the dependencies. For example, if an effect specifies `[]` as the second argument but reads `someProp` inside, it will keep "seeing" the initial value of `someProp`. The solution is to either remove the dependency array, or to fix it. Here's [how you can deal with functions](#is-it-safe-to-omit-functions-from-the-list-of-dependencies), and here's [other common strategies](#what-can-i-do-if-my-effect-dependencies-change-too-often) to run effects less often without incorrectly skipping dependencies. + +>Note +> +>We provide an [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. + ### How do I implement `getDerivedStateFromProps`? {#how-do-i-implement-getderivedstatefromprops} While you probably [don't need it](/blog/2018/06/07/you-probably-dont-need-derived-state.html), in rare cases that you do (such as implementing a `` component), you can update the state right during rendering. React will re-run the component with updated state immediately after exiting the first render so it wouldn't be expensive. @@ -416,6 +462,207 @@ If you're not familiar with this syntax, check out the [explanation](/docs/hooks Yes. See [conditionally firing an effect](/docs/hooks-reference.html#conditionally-firing-an-effect). Note that forgetting to handle updates often [introduces bugs](/docs/hooks-effect.html#explanation-why-effects-run-on-each-update), which is why this isn't the default behavior. +### Is it safe to omit functions from the list of dependencies? {#is-it-safe-to-omit-functions-from-the-list-of-dependencies} + +Generally speaking, no. + +```js{3,8} +function Example() { + function doSomething() { + console.log(someProp); + } + + useEffect(() => { + doSomething(); + }, []); // 🔴 This is not safe (it calls `doSomething` which uses `someProp`) +} +``` + +It's difficult to remember which props or state are used by functions outside of the effect. This is why **usually you'll want to declare functions needed by an effect *inside* of it.** Then it's easy to see what values from the component scope that effect depends on: + +```js{4,8} +function Example() { + useEffect(() => { + function doSomething() { + console.log(someProp); + } + + doSomething(); + }, [someProp]); // ✅ OK (our effect only uses `someProp`) +} +``` + +If after that we still don't use any values from the component scope, it's safe to specify `[]`: + +```js{7} +useEffect(() => { + function doSomething() { + console.log('hello'); + } + + doSomething(); +}, []); // ✅ OK in this example because we don't use *any* values from component scope +``` + +Depending on your use case, there are a few more options described below. + +>Note +> +>We provide the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) ESLint rule as a part of the [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It help you find components that don't handle updates consistently. + +Let's see why this matters. + +If you specify a [list of dependencies](/docs/hooks-reference.html#conditionally-firing-an-effect) as the last argument to `useEffect`, `useMemo`, `useCallback`, or `useImperativeHandle`, it must include all values used inside that participate in the React data flow. That includes props, state, and anything derived from them. + +It is **only** safe to omit a function from the dependency list if nothing in it (or the functions called by it) references props, state, or values derived from them. This example has a bug: + +```js{5,12} +function ProductPage({ productId }) { + const [product, setProduct] = useState(null); + + async function fetchProduct() { + const response = await fetch('http://myapi/product' + productId); // Uses productId prop + const json = await response.json(); + setProduct(json); + } + + useEffect(() => { + fetchProduct(); + }, []); // 🔴 Invalid because `fetchProduct` uses `productId` + // ... +} +``` + +**The recommended fix is to move that function _inside_ of your effect**. That makes it easy to see which props or state your effect uses, and to ensure they're all declared: + +```js{5-10,13} +function ProductPage({ productId }) { + const [product, setProduct] = useState(null); + + useEffect(() => { + // By moving this function inside the effect, we can clearly see the values it uses. + async function fetchProduct() { + const response = await fetch('http://myapi/product' + productId); + const json = await response.json(); + setProduct(json); + } + + fetchProduct(); + }, [productId]); // ✅ Valid because our effect only uses productId + // ... +} +``` + +This also allows you to handle out-of-order responses with a local variable inside the effect: + +```js{2,6,8} + useEffect(() => { + let ignore = false; + async function fetchProduct() { + const response = await fetch('http://myapi/product/' + productId); + const json = await response.json(); + if (!ignore) setProduct(json); + } + return () => { ignore = true }; + }, [productId]); +``` + +We moved the function inside the effect so it doesn't need to be in its dependency list. + +>Tip +> +>Check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. + +**If for some reason you _can't_ move a function inside an effect, there are a few more options:** + +* **You can try moving that function outside of your component**. In that case, the function is guaranteed to not reference any props or state, and also doesn't need to be in the list of dependencies. +* If the function you're calling is a pure computation and is safe to call while rendering, you may **call it outside of the effect instead,** and make the effect depend on the returned value. +* As a last resort, you can **add a function to effect dependencies but _wrap its definition_** into the [`useCallback`](/docs/hooks-reference.html#usecallback) Hook. This ensures it doesn't change on every render unless *its own* dependencies also change: + +```js{2-5} +function ProductPage({ productId }) { + // ✅ Wrap with useCallback to avoid change on every render + const fetchProduct = useCallback(() => { + // ... Does something with productId ... + }, [productId]); // ✅ All useCallback dependencies are specified + + return ; +} + +function ProductDetails({ fetchProduct }) + useEffect(() => { + fetchProduct(); + }, [fetchProduct]); // ✅ All useEffect dependencies are specified + // ... +} +``` + +Note that in the above example we **need** to keep the function in the dependencies list. This ensures that a change in the `productId` prop of `ProductPage` automatically triggers a refetch in the `ProductDetails` component. + +### What can I do if my effect dependencies change too often? + +Sometimes, your effect may be using reading state that changes too often. You might be tempted to omit that state from a list of dependencies, but that usually leads to bugs: + +```js{6,9} +function Counter() { + const [count, setCount] = useState(0); + + useEffect(() => { + const id = setInterval(() => { + setCount(count + 1); // This effect depends on the `count` state + }, 1000); + return () => clearInterval(id); + }, []); // 🔴 Bug: `count` is not specified as a dependency + + return

{count}

; +} +``` + +Specifying `[count]` as a list of dependencies would fix the bug, but would cause the interval to be reset on every change. That may not be desirable. To fix this, we can use the [functional update form of `setState`](/docs/hooks-reference.html#functional-updates). It lets us specify *how* the state needs to change without referencing the *current* state: + +```js{6,9} +function Counter() { + const [count, setCount] = useState(0); + + useEffect(() => { + const id = setInterval(() => { + setCount(c => c + 1); // ✅ This doesn't depend on `count` variable outside + }, 1000); + return () => clearInterval(id); + }, []); // ✅ Our effect doesn't use any variables in the component scope + + return

{count}

; +} +``` + +(The identity of the `setCount` function is guaranteed to be stable so it's safe to omit.) + +In more complex cases (such as if one state depends on another state), try moving the state update logic outside the effect with the [`useReducer` Hook](/docs/hooks-reference.html#usereducer). [This article](https://adamrackis.dev/state-and-use-reducer/) offers an example of how you can do this. **The identity of the `dispatch` function from `useReducer` is always stable** — even if the reducer function is declared inside the component and reads its props. + +As a last resort, if you want to something like `this` in a class, you can [use a ref](/docs/hooks-faq.html#is-there-something-like-instance-variables) to hold a mutable variable. Then you can write and read to it. For example: + +```js{2-6,10-11,16} +function Example(props) { + // Keep latest props in a ref. + let latestProps = useRef(props); + useEffect(() => { + latestProps.current = props; + }); + + useEffect(() => { + function tick() { + // Read latest props at any time + console.log(latestProps.current); + } + + const id = setInterval(tick, 1000); + return () => clearInterval(id); + }, []); // This effect never re-runs +} +``` + +Only do this if you couldn't find a better alternative, as relying on mutation makes components less predictable. If there's a specific pattern that doesn't translate well, [file an issue](https://github.com/facebook/react/issues/new) with a runnable example code and we can try to help. + ### How do I implement `shouldComponentUpdate`? {#how-do-i-implement-shouldcomponentupdate} You can wrap a function component with `React.memo` to shallowly compare its props: @@ -430,7 +677,6 @@ It's not a Hook because it doesn't compose like Hooks do. `React.memo` is equiva `React.memo` doesn't compare state because there is no single state object to compare. But you can make children pure too, or even [optimize individual children with `useMemo`](/docs/hooks-faq.html#how-to-memoize-calculations). - ### How to memoize calculations? {#how-to-memoize-calculations} The [`useMemo`](/docs/hooks-reference.html#usememo) Hook lets you cache calculations between multiple renders by "remembering" the previous computation: diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index deeef54cf..4466bc83b 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -45,6 +45,10 @@ setState(newState); During subsequent re-renders, the first value returned by `useState` will always be the most recent state after applying updates. +>Note +> +>React guarantees that `setState` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list. + #### Functional updates {#functional-updates} If the new state is computed using the previous state, you can pass a function to `setState`. The function will receive the previous value, and return an updated value. Here's an example of a counter component that uses both forms of `setState`: @@ -133,7 +137,7 @@ Although `useEffect` is deferred until after the browser has painted, it's guara #### Conditionally firing an effect {#conditionally-firing-an-effect} -The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its inputs changes. +The default behavior for effects is to fire the effect after every completed render. That way an effect is always recreated if one of its dependencies changes. However, this may be overkill in some cases, like the subscription example from the previous section. We don't need to create a new subscription on every update, only if the `source` props has changed. @@ -153,11 +157,18 @@ useEffect( Now the subscription will only be recreated when `props.source` changes. -Passing in an empty array `[]` of inputs tells React that your effect doesn't depend on any values from the component, so that effect would run only on mount and clean up on unmount; it won't run on updates. - -> Note +>Note +> +>If you use this optimization, make sure the array includes **all values from the component scope (such as props and state) that change over time and that are used by the effect**. Otherwise, your code will reference stale values from previous renders. Learn more about [how to deal with functions](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) and what to do when the [array values change too often](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often). +> +>If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array (`[]`) as a second argument. This tells React that your effect doesn't depend on *any* values from props or state, so it never needs to re-run. This isn't handled as a special case -- it follows directly from how the dependencies array always works. > -> The array of inputs is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. +>If you pass an empty array (`[]`), the props and state as inside the effect will always have their initial values. While passing `[]` as the second argument is closer to the familiar `componentDidMount` and `componentWillUnmount` mental model, there are usually [better](/docs/hooks-faq.html#is-it-safe-to-omit-functions-from-the-list-of-dependencies) [solutions](/docs/hooks-faq.html#what-can-i-do-if-my-effect-dependencies-change-too-often) to avoid re-running effects too often. Also, don't forget that React defers running `useEffect` until after the browser has painted, so doing extra work is less of a problem. +> +> +>We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. + +The array of dependencies is not passed as arguments to the effect function. Conceptually, though, that's what they represent: every value referenced inside the effect function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. ### `useContext` {#usecontext} @@ -211,6 +222,10 @@ function Counter({initialState}) { } ``` +>Note +> +>React guarantees that `dispatch` function identity is stable and won't change on re-renders. This is why it's safe to omit from the `useEffect` or `useCallback` dependency list. + #### Specifying the initial state {#specifying-the-initial-state} There’s two different ways to initialize `useReducer` state. You may choose either one depending on the use case. The simplest way to pass the initial state as a second argument: @@ -283,13 +298,15 @@ const memoizedCallback = useCallback( Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) callback. -Pass an inline callback and an array of inputs. `useCallback` will return a memoized version of the callback that only changes if one of the inputs has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`). +Pass an inline callback and an array of dependencies. `useCallback` will return a memoized version of the callback that only changes if one of the dependencies has changed. This is useful when passing callbacks to optimized child components that rely on reference equality to prevent unnecessary renders (e.g. `shouldComponentUpdate`). -`useCallback(fn, inputs)` is equivalent to `useMemo(() => fn, inputs)`. +`useCallback(fn, deps)` is equivalent to `useMemo(() => fn, deps)`. > Note > -> The array of inputs is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. +> The array of dependencies is not passed as arguments to the callback. Conceptually, though, that's what they represent: every value referenced inside the callback should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. +> +> We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. ### `useMemo` {#usememo} @@ -299,7 +316,7 @@ const memoizedValue = useMemo(() => computeExpensiveValue(a, b), [a, b]); Returns a [memoized](https://en.wikipedia.org/wiki/Memoization) value. -Pass a "create" function and an array of inputs. `useMemo` will only recompute the memoized value when one of the inputs has changed. This optimization helps to avoid expensive calculations on every render. +Pass a "create" function and an array of dependencies. `useMemo` will only recompute the memoized value when one of the dependencies has changed. This optimization helps to avoid expensive calculations on every render. Remember that the function passed to `useMemo` runs during rendering. Don't do anything there that you wouldn't normally do while rendering. For example, side effects belong in `useEffect`, not `useMemo`. @@ -309,7 +326,9 @@ If no array is provided, a new value will be computed whenever a new function in > Note > -> The array of inputs is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the inputs array. In the future, a sufficiently advanced compiler could create this array automatically. +> The array of dependencies is not passed as arguments to the function. Conceptually, though, that's what they represent: every value referenced inside the function should also appear in the dependencies array. In the future, a sufficiently advanced compiler could create this array automatically. +> +> We recommend using the [`exhaustive-deps`](https://github.com/facebook/react/issues/14920) rule as part of our [`eslint-plugin-react-hooks`](https://www.npmjs.com/package/eslint-plugin-react-hooks#installation) package. It warns when dependencies are specified incorrectly and suggests a fix. ### `useRef` {#useref} @@ -342,7 +361,7 @@ Note that `useRef()` is useful for more than the `ref` attribute. It's [handy fo ### `useImperativeHandle` {#useimperativehandle} ```js -useImperativeHandle(ref, createHandle, [inputs]) +useImperativeHandle(ref, createHandle, [deps]) ``` `useImperativeHandle` customizes the instance value that is exposed to parent components when using `ref`. As always, imperative code using refs should be avoided in most cases. `useImperativeHandle` should be used with `forwardRef`: diff --git a/content/docs/hooks-rules.md b/content/docs/hooks-rules.md index 698d1c741..8c332578c 100644 --- a/content/docs/hooks-rules.md +++ b/content/docs/hooks-rules.md @@ -40,7 +40,8 @@ npm install eslint-plugin-react-hooks ], "rules": { // ... - "react-hooks/rules-of-hooks": "error" + "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks + "react-hooks/exhaustive-deps": "warning" // Checks effect dependencies } } ``` From 83faa76713205d2c669005d6d51d29ee65079cf7 Mon Sep 17 00:00:00 2001 From: Victoria Quirante Date: Wed, 13 Mar 2019 16:28:05 +0100 Subject: [PATCH 014/152] Add React Alicante 2019 (#1819) --- content/community/conferences.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/content/community/conferences.md b/content/community/conferences.md index 89ed871d0..e138b119a 100644 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -76,6 +76,11 @@ September 26-28, 2019 in Goa, India [Website](https://www.reactindia.io/) - [Twitter](https://twitter.com/react_india) - [Facebook](https://www.facebook.com/ReactJSIndia) +### React Alicante 2019 {#react-alicante-2019} +September 26-28, 2019 in Alicante, Spain + +[Website](http://reactalicante.es/) - [Twitter](https://twitter.com/reactalicante) - [Facebook](https://www.facebook.com/ReactAlicante) + ## Past Conferences {#past-conferences} ### React.js Conf 2015 {#reactjs-conf-2015} From 110a318d1efc7d2c60644bd160dcac359b8778fb Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 13 Mar 2019 15:38:51 +0000 Subject: [PATCH 015/152] Link to a data fetching demo --- content/docs/hooks-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index 6145b968d..1f36f5f17 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -210,7 +210,7 @@ There are a few more heuristics, and they might change over time as we fine-tune ### How can I do data fetching with Hooks? -Check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. +Here is a [small demo](https://codesandbox.io/s/pwm32zx7z7) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. ### Is there something like instance variables? {#is-there-something-like-instance-variables} From 474de38b2c1e9dc8d9e6cc30b1cb0e8ff4ae3628 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 13 Mar 2019 15:42:01 +0000 Subject: [PATCH 016/152] Use another example --- content/docs/hooks-faq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index 1f36f5f17..df6d9f7c3 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -210,7 +210,7 @@ There are a few more heuristics, and they might change over time as we fine-tune ### How can I do data fetching with Hooks? -Here is a [small demo](https://codesandbox.io/s/pwm32zx7z7) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. +Here is a [small demo](https://codesandbox.io/s/jvvkoo8pq3) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. ### Is there something like instance variables? {#is-there-something-like-instance-variables} @@ -571,7 +571,7 @@ We moved the function inside the effect so it doesn't need to be in its dependen >Tip > ->Check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. +>Check out [this small demo](https://codesandbox.io/s/jvvkoo8pq3) and [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. **If for some reason you _can't_ move a function inside an effect, there are a few more options:** From 877b1897588c7c4640ecf1f6841adfe3986c44b8 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 13 Mar 2019 15:46:05 +0000 Subject: [PATCH 017/152] Fix wording --- content/docs/hooks-faq.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index df6d9f7c3..0540031ba 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -210,7 +210,7 @@ There are a few more heuristics, and they might change over time as we fine-tune ### How can I do data fetching with Hooks? -Here is a [small demo](https://codesandbox.io/s/jvvkoo8pq3) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) to learn more about data fetching with Hooks. +Here is a [small demo](https://codesandbox.io/s/jvvkoo8pq3) to get you started. To learn more, check out [this article](https://www.robinwieruch.de/react-hooks-fetch-data/) about data fetching with Hooks. ### Is there something like instance variables? {#is-there-something-like-instance-variables} From 352c3ff01f437de2441533313bb1feb2c3f87414 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Wed, 13 Mar 2019 18:24:10 +0000 Subject: [PATCH 018/152] Fix example --- content/docs/hooks-faq.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index 0540031ba..9016fa7f4 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -467,7 +467,7 @@ Yes. See [conditionally firing an effect](/docs/hooks-reference.html#conditional Generally speaking, no. ```js{3,8} -function Example() { +function Example({ someProp }) { function doSomething() { console.log(someProp); } @@ -481,7 +481,7 @@ function Example() { It's difficult to remember which props or state are used by functions outside of the effect. This is why **usually you'll want to declare functions needed by an effect *inside* of it.** Then it's easy to see what values from the component scope that effect depends on: ```js{4,8} -function Example() { +function Example({ someProp }) { useEffect(() => { function doSomething() { console.log(someProp); From 3e489fc2f9a028d570ccfdd74ddbc93faea27d32 Mon Sep 17 00:00:00 2001 From: Manuel Bieh Date: Thu, 14 Mar 2019 01:09:09 +0100 Subject: [PATCH 019/152] Fixing incorrect value for eslint rule (#1824) The name for the "warning" level in ESLint is `warn` not `warning` (https://eslint.org/docs/user-guide/configuring#configuring-rules) --- content/docs/hooks-rules.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/hooks-rules.md b/content/docs/hooks-rules.md index 8c332578c..dbac9cffd 100644 --- a/content/docs/hooks-rules.md +++ b/content/docs/hooks-rules.md @@ -41,7 +41,7 @@ npm install eslint-plugin-react-hooks "rules": { // ... "react-hooks/rules-of-hooks": "error", // Checks rules of Hooks - "react-hooks/exhaustive-deps": "warning" // Checks effect dependencies + "react-hooks/exhaustive-deps": "warn" // Checks effect dependencies } } ``` From 40bbbd5b102cd33bdee85fcc4bd209dc06585975 Mon Sep 17 00:00:00 2001 From: Dimitar Nestorov Date: Thu, 14 Mar 2019 16:49:11 +0200 Subject: [PATCH 020/152] Updating useMemo docs (#1796) https://codesandbox.io/s/4x68k8nrw --- content/docs/hooks-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index 4466bc83b..4daf0f191 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -320,7 +320,7 @@ Pass a "create" function and an array of dependencies. `useMemo` will only recom Remember that the function passed to `useMemo` runs during rendering. Don't do anything there that you wouldn't normally do while rendering. For example, side effects belong in `useEffect`, not `useMemo`. -If no array is provided, a new value will be computed whenever a new function instance is passed as the first argument. (With an inline function, on every render.) +If no array is provided, a new value will be computed on every render. **You may rely on `useMemo` as a performance optimization, not as a semantic guarantee.** In the future, React may choose to "forget" some previously memoized values and recalculate them on next render, e.g. to free memory for offscreen components. Write your code so that it still works without `useMemo` — and then add it to optimize performance. From 1fe2e0ae29b2fe8a8a09ab10048bb9fe284ff568 Mon Sep 17 00:00:00 2001 From: Nelson Reitz Date: Fri, 15 Mar 2019 15:04:19 +0100 Subject: [PATCH 021/152] Fix overflowing headers on small screens (#1830) --- src/theme.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/theme.js b/src/theme.js index 9f440d56d..a4d445206 100644 --- a/src/theme.js +++ b/src/theme.js @@ -89,6 +89,11 @@ const fonts = { lineHeight: '65px', fontWeight: 700, + [media.lessThan('small')]: { + overflowWrap: 'break-word', + wordBreak: 'break-word', + }, + [media.lessThan('medium')]: { fontSize: 40, lineHeight: '45px', From 877431a60bb64c4694d51cca79dfc4230d6af603 Mon Sep 17 00:00:00 2001 From: Arthur Denner Date: Sun, 17 Mar 2019 18:08:17 -0300 Subject: [PATCH 022/152] Fix previous article on hooks-effect.md (#1802) Hi! :wave: This PR only fixes the `Previous article` link on [this page](https://reactjs.org/docs/hooks-effect.html). Once this get merged, do I need to open a similar PR in each one of the translation repos? --- content/docs/hooks-effect.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/hooks-effect.md b/content/docs/hooks-effect.md index fd7d89592..73d6a3d2c 100644 --- a/content/docs/hooks-effect.md +++ b/content/docs/hooks-effect.md @@ -3,7 +3,7 @@ id: hooks-state title: Using the Effect Hook permalink: docs/hooks-effect.html next: hooks-rules.html -prev: hooks-intro.html +prev: hooks-state.html --- *Hooks* are a new addition in React 16.8. They let you use state and other React features without writing a class. From 905a1134c07ea24aa4e4e4351371cf77b027280a Mon Sep 17 00:00:00 2001 From: Brian Mitchell Date: Mon, 18 Mar 2019 12:24:24 -0500 Subject: [PATCH 023/152] Add React Rally 2019 (#1840) --- content/community/conferences.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/content/community/conferences.md b/content/community/conferences.md index e138b119a..ea8613c78 100644 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -57,6 +57,11 @@ July 15-21, 2019. New York City, USA [Website](https://reactweek.nyc) - [Twitter](https://twitter.com/ReactWeek) +### React Rally 2019 +August 22-23, 2019. Salt Lake City, USA. + +[Website](https://www.reactrally.com/) - [Twitter](https://twitter.com/ReactRally) - [Instagram](https://www.instagram.com/reactrally/) + ### ComponentsConf 2019 {#componentsconf-2019} September 6, 2019 in Melbourne, Australia [Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf) From 1970ebebae2e7bd23c33c8029c66885832aace04 Mon Sep 17 00:00:00 2001 From: Riza Fahmi Date: Tue, 19 Mar 2019 00:52:02 +0700 Subject: [PATCH 024/152] Translate typechecking-with-proptypes (#40) * Translate typechecking-with-proptypes * Revise some stuff: Anda, komentar, and other stuff --- content/docs/typechecking-with-proptypes.md | 78 ++++++++++----------- 1 file changed, 39 insertions(+), 39 deletions(-) diff --git a/content/docs/typechecking-with-proptypes.md b/content/docs/typechecking-with-proptypes.md index 4004e7820..27b9dbf40 100644 --- a/content/docs/typechecking-with-proptypes.md +++ b/content/docs/typechecking-with-proptypes.md @@ -1,6 +1,6 @@ --- id: typechecking-with-proptypes -title: Typechecking With PropTypes +title: Pengecekan Tipe Dengan PropTypes permalink: docs/typechecking-with-proptypes.html redirect_from: - "docs/react-api.html#typechecking-with-proptypes" @@ -8,11 +8,11 @@ redirect_from: > Note: > -> `React.PropTypes` has moved into a different package since React v15.5. Please use [the `prop-types` library instead](https://www.npmjs.com/package/prop-types). +> `React.PropTypes` sudah dipindahkan ke paket yang berbeda sejak React v15.5. Silakan gunakan [pustaka `prop-types`](https://www.npmjs.com/package/prop-types). > ->We provide [a codemod script](/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactproptypes) to automate the conversion. +>Kami menyediakan [*codemod script*](/blog/2017/04/07/react-v15.5.0.html#migrating-from-reactproptypes) untuk melakukan konversi secara otomatis. -As your app grows, you can catch a lot of bugs with typechecking. For some applications, you can use JavaScript extensions like [Flow](https://flow.org/) or [TypeScript](https://www.typescriptlang.org/) to typecheck your whole application. But even if you don't use those, React has some built-in typechecking abilities. To run typechecking on the props for a component, you can assign the special `propTypes` property: +Dengan berkembangnya aplikasi anda, kit dapat menemukan banyak kesalahan atau *bugs* dengan pengecekan tipe. Untuk beberapa aplikasi, anda dapat menggunakan ekstensi JavaScript seperti [Flow](https://flow.org/) atau [TypeScript](https://www.typescriptlang.org/) untuk melakukan pengecekan tipe di aplikasi secara menyeluruh. Meskipun kamu tidak menggunakannya, React memiliki kemampuan pengecekan tipe. Untuk menjalankan pengecekan terhadap *props* disebuah komponen, kamu dapat menggunakan properti khusus `propTypes`: ```javascript import PropTypes from 'prop-types'; @@ -30,18 +30,18 @@ Greeting.propTypes = { }; ``` -`PropTypes` exports a range of validators that can be used to make sure the data you receive is valid. In this example, we're using `PropTypes.string`. When an invalid value is provided for a prop, a warning will be shown in the JavaScript console. For performance reasons, `propTypes` is only checked in development mode. +`PropTypes` mengirimkan berbagai jenis *validator* yang dapat digunakan untuk memastikan bahwa data yang diterima valid. Contoh diatas, anda menggunakan `PropTypes.string`. Ketika nilai yang dikirimkan untuk sebuah *prop* keliru, sebuah peringatan akan muncul di konsol JavaScript. Untuk alasan performa, `propTypes` hanya melakukan pengecekan di mode pengembangan atau *development*. ### PropTypes {#proptypes} -Here is an example documenting the different validators provided: +Berikut contoh mendokumentasikan berbagai validator yang berbeda yang sudah disediakan: ```javascript import PropTypes from 'prop-types'; MyComponent.propTypes = { - // You can declare that a prop is a specific JS type. By default, these - // are all optional. + // Anda dapat menyatakan bahwa sebuah prop adalah tipe khusus yang berasal dari JS. Secara default, + // hal ini sifatnya opsional. optionalArray: PropTypes.array, optionalBool: PropTypes.bool, optionalFunc: PropTypes.func, @@ -50,50 +50,50 @@ MyComponent.propTypes = { optionalString: PropTypes.string, optionalSymbol: PropTypes.symbol, - // Anything that can be rendered: numbers, strings, elements or an array - // (or fragment) containing these types. + // Apapun dapat di-render: numbers, strings, elements ataupun sebuah array + // (atau fragmen) yang mengandung tipe-tipe tersebut. optionalNode: PropTypes.node, - // A React element. + // Sebuah elemen React. optionalElement: PropTypes.element, - // You can also declare that a prop is an instance of a class. This uses - // JS's instanceof operator. + // Anda dapat juga menyatakan bahwa sebuah prop adalah instance dari sebuah kelas. Ini menggunakan + // operator instanceof dari JS. optionalMessage: PropTypes.instanceOf(Message), - // You can ensure that your prop is limited to specific values by treating - // it as an enum. + // Anda dapat memastikan bahwa prop anda dibatasi khusus untuk nilai tertentu dengan memperlakukan + // sebagai sebuah enum. optionalEnum: PropTypes.oneOf(['News', 'Photos']), - // An object that could be one of many types + // Sebuah objek dapat memiliki satu dari banyak tipe-tipe optionalUnion: PropTypes.oneOfType([ PropTypes.string, PropTypes.number, PropTypes.instanceOf(Message) ]), - // An array of a certain type + // Sebuah array dari tipe tertentu optionalArrayOf: PropTypes.arrayOf(PropTypes.number), - // An object with property values of a certain type + // Sebuah objek dengan nilai properti dari tipe tertentu optionalObjectOf: PropTypes.objectOf(PropTypes.number), - // An object taking on a particular shape + // Sebuah objek yang menerima bentuk tertentu optionalObjectWithShape: PropTypes.shape({ color: PropTypes.string, fontSize: PropTypes.number }), - // You can chain any of the above with `isRequired` to make sure a warning - // is shown if the prop isn't provided. + // Anda dapat merangkai dari contoh diatas dengan `isRequired` untuk memastikan sebuah peringatan + // akan muncul jika sebuah prop tidak disertakan. requiredFunc: PropTypes.func.isRequired, - // A value of any data type + // Sebuah nilai dari tipe data apapun requiredAny: PropTypes.any.isRequired, - // You can also specify a custom validator. It should return an Error - // object if the validation fails. Don't `console.warn` or throw, as this - // won't work inside `oneOfType`. + // Anda dapat juga menentukan validator khusus. Akan menghasilkan objek Error + // jika validasi gagal. Jangan `console.warn` atau `throw`, hal seperti ini + // tidak akan berfungsi jika didalam `oneOfType`. customProp: function(props, propName, componentName) { if (!/matchme/.test(props[propName])) { return new Error( @@ -103,11 +103,11 @@ MyComponent.propTypes = { } }, - // You can also supply a custom validator to `arrayOf` and `objectOf`. - // It should return an Error object if the validation fails. The validator - // will be called for each key in the array or object. The first two - // arguments of the validator are the array or object itself, and the - // current item's key. + // Anda dapat juga menyediakan sebuah validator tambahan ke `arrayOf` dan `objectOf`. + // Hal ini sebaiknya menghasilkan objek Error jika validasi gagal. Validator + // akan dipanggil untuk setiap nilai didalam array atau objek. Dua pertama + // dari argumen validator adalah array atau objek itu sendiri, dan + // identitas dari nilai saat itu. customArrayProp: PropTypes.arrayOf(function(propValue, key, componentName, location, propFullName) { if (!/matchme/.test(propValue[key])) { return new Error( @@ -119,16 +119,16 @@ MyComponent.propTypes = { }; ``` -### Requiring Single Child {#requiring-single-child} +### Membutuhkan Satu Komponen Anak {#requiring-single-child} -With `PropTypes.element` you can specify that only a single child can be passed to a component as children. +Dengan menggunakan `PropTypes.element` anda dapat menentukan bahwa hanya menerima satu komponen anak yang dapat dikirimkan ke komponen lain. ```javascript import PropTypes from 'prop-types'; class MyComponent extends React.Component { render() { - // This must be exactly one element or it will warn. + // Harus memiliki hanya satu elemen atau akan diberi peringatan. const children = this.props.children; return (
@@ -143,9 +143,9 @@ MyComponent.propTypes = { }; ``` -### Default Prop Values {#default-prop-values} +### Nilai Default Prop {#default-prop-values} -You can define default values for your `props` by assigning to the special `defaultProps` property: +Anda dapat mendefinisikan nilai *default* untuk `props` dengan menambahkan properti khusus `defaultProps`: ```javascript class Greeting extends React.Component { @@ -156,19 +156,19 @@ class Greeting extends React.Component { } } -// Specifies the default values for props: +// Menentukan nilai default dari props: Greeting.defaultProps = { name: 'Stranger' }; -// Renders "Hello, Stranger": +// Render "Hello, Stranger": ReactDOM.render( , document.getElementById('example') ); ``` -If you are using a Babel transform like [transform-class-properties](https://babeljs.io/docs/plugins/transform-class-properties/) , you can also declare `defaultProps` as static property within a React component class. This syntax has not yet been finalized though and will require a compilation step to work within a browser. For more information, see the [class fields proposal](https://github.com/tc39/proposal-class-fields). +Jika kamu menggunakan alat transformasi Babel seperti [transform-class-properties](https://babeljs.io/docs/plugins/transform-class-properties/) , kamu dapat mendeklarasikan `defaultProps` sebagai properti *static* dalam komponen kelas React. Sintaks ini belum final dan akan membutuhkan tahapan kompilasi untuk berjalan di browser. Informasi lebih lanjut, silakan lihat [proposal class fields](https://github.com/tc39/proposal-class-fields). ```javascript class Greeting extends React.Component { @@ -184,4 +184,4 @@ class Greeting extends React.Component { } ``` -The `defaultProps` will be used to ensure that `this.props.name` will have a value if it was not specified by the parent component. The `propTypes` typechecking happens after `defaultProps` are resolved, so typechecking will also apply to the `defaultProps`. +Properti `defaultProps` akan digunakan untuk memastikan bahwa `this.props.name` akan memiliki sebuah nilai jika tidak ada nilai yang diberikan oleh komponen induknya. Proses pengecekan tipe `propTypes` akan dijalankan setelah `defaultProps` berjalan, sehingga proses pengecekan tipe juga akan berlaku untuk `defaultProps`. From 00ba2a313e1ac5add176003d62540bf1d2116bc1 Mon Sep 17 00:00:00 2001 From: Andre Pratama Date: Tue, 19 Mar 2019 02:01:06 +0800 Subject: [PATCH 025/152] Translating component-and-props page (#19) * edit commponent props * start-translation * edit semantics * fixing some translated word properly * fixing typo * fixing translated word * fixing error space * fixing incomplete translate * docs: minor fixes --- content/docs/components-and-props.md | 133 +++++++++++++++++---------- 1 file changed, 84 insertions(+), 49 deletions(-) diff --git a/content/docs/components-and-props.md b/content/docs/components-and-props.md index 4b3bbb6e6..73028c0de 100644 --- a/content/docs/components-and-props.md +++ b/content/docs/components-and-props.md @@ -1,6 +1,6 @@ --- id: components-and-props -title: Components and Props +title: Komponen and Props permalink: docs/components-and-props.html redirect_from: - "docs/reusable-components.html" @@ -16,57 +16,63 @@ prev: rendering-elements.html next: state-and-lifecycle.html --- -Components let you split the UI into independent, reusable pieces, and think about each piece in isolation. This page provides an introduction to the idea of components. You can find a [detailed component API reference here](/docs/react-component.html). +Komponen mempermudah Anda untuk memecah antarmuka pengguna menjadi bagian tersendiri, bagian yang bisa digunakan kembali, dan berpikir tentang setiap potongan dalam isolasi. +Halaman ini memberikan pengantar tentang ide komponen. Anda dapat menemukan +[rujukan API komponen terperinci di sini](/docs/react-component.html) -Conceptually, components are like JavaScript functions. They accept arbitrary inputs (called "props") and return React elements describing what should appear on the screen. +Secara konsep, komponen mirip dengan fungsi pada Javascript. Komponen menerima beberapa masukan (biasa disebut *"props"*) dan mengembalikan element React yang mendeskripsikan apa yang seharusnya tampil pada layar. -## Function and Class Components {#function-and-class-components} +## Fungsi dan Komponen Kelas {#function-and-class-components} -The simplest way to define a component is to write a JavaScript function: +Cara paling sederhana untuk mendefinisikan sebuah komponen adalah dengan +menuliskan sebuah fungsi Javascript: ```js function Welcome(props) { - return

Hello, {props.name}

; + return

Halo, {props.name}

; } ``` -This function is a valid React component because it accepts a single "props" (which stands for properties) object argument with data and returns a React element. We call such components "function components" because they are literally JavaScript functions. +Fungsi ini adalah komponen React yang sah karena menerima sebuah *"props"* tunggal (yang bertindak sebagai *props*) atau argumen objek dengan data dan kembalian sebuah elemen React. Kita menyebut komponen karena itu benar-benar merupakan fungsi Javascript. -You can also use an [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) to define a component: +Anda juga dapat menggunakan sebuah [ES6 class](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Classes) untuk mendefinisikan sebuah komponen: ```js class Welcome extends React.Component { render() { - return

Hello, {this.props.name}

; + return

Halo, {this.props.name}

; } } ``` -The above two components are equivalent from React's point of view. +Dari sudut pandang React, kedua komponen di atas mempunyai nilai yang sama. -Classes have some additional features that we will discuss in the [next sections](/docs/state-and-lifecycle.html). Until then, we will use function components for their conciseness. +Kelas mempunyai beberapa fitur tambahan yang akan kita diskusikan di [sesi selanjutnya](/docs/state-and-lifecycle.html). Sampai di sini, kita akan menggunakan komponen fungsional untuk mempersingkatnya. -## Rendering a Component {#rendering-a-component} +## Merender sebuah Komponen {#rendering-a-component} -Previously, we only encountered React elements that represent DOM tags: +Sebelumnya, kita hanya menemui elemen React yang mewakili *tag* DOM: ```js const element =
; ``` -However, elements can also represent user-defined components: +Namun, elemen juga dapat mewakilkan komponen yang didefinisikan +oleh pengguna: ```js const element = ; ``` -When React sees an element representing a user-defined component, it passes JSX attributes to this component as a single object. We call this object "props". +Ketika React melihat sebuah element mewakili sebuah komponen yang dibuat oleh +pengguna, komponen mengoper atribut JSX ke dalam komponen ini sebagai +*single-object*. -For example, this code renders "Hello, Sara" on the page: +Sebagai contoh, kode ini akan me-*render* "Halo, Sara" pada laman: ```js{1,5} function Welcome(props) { - return

Hello, {props.name}

; + return

Halo, {props.name}

; } const element = ; @@ -78,28 +84,37 @@ ReactDOM.render( [](codepen://components-and-props/rendering-a-component) -Let's recap what happens in this example: +Mari merangkum apa yang terjadi pada contoh berikut: -1. We call `ReactDOM.render()` with the `` element. -2. React calls the `Welcome` component with `{name: 'Sara'}` as the props. -3. Our `Welcome` component returns a `

Hello, Sara

` element as the result. -4. React DOM efficiently updates the DOM to match `

Hello, Sara

`. +1. Kita memanggil `ReactDOM.render()` dengan elemen ``. +2. React memanggil komponen `Welcome` dengan `{name: 'Sara'}` sebagai + propertinya. +3. Komponen `Welcome` kita akan mengembalikan sebuah element `

Halo, + SaraHalo, Sara`. ->**Note:** Always start component names with a capital letter. +>**Catatan:** Selalu awali nama komponen dengan sebuah huruf kapital. > ->React treats components starting with lowercase letters as DOM tags. For example, `
` represents an HTML div tag, but `` represents a component and requires `Welcome` to be in scope. +>React memperlakukan awalan komponen dengan huruf kecil sebagai *tag* dari DOM. +>Sebagai contoh, `
`, merepresentasikan sebuah HTML div *tag*, tetapi +>`` merepresentasikan sebuah komponen dan membutuhkan Welcome to be +>in scope. > ->To learn more about the reasoning behind this convention, please read [JSX In Depth](/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized). +>Anda dapat membaca lebih lanjut tentang alasan dibalik Konvensi tersebut [di sini.](/docs/jsx-in-depth.html#user-defined-components-must-be-capitalized) -## Composing Components {#composing-components} +## Menyusun Komponen {#composing-components} -Components can refer to other components in their output. This lets us use the same component abstraction for any level of detail. A button, a form, a dialog, a screen: in React apps, all those are commonly expressed as components. +Komponen dapat merujuk ke komponen lain pada keluaran mereka. Ini memungkinkan kita untuk menggunakan +abstraksi dari komponen yang sama untuk semua tingkat detail. Sebuah tombol, +sebuah *form*, sebuah dialog, sebuah tampilan: di dalam aplikasi React, semua +itu dinyatakan dalam bentuk komponen. -For example, we can create an `App` component that renders `Welcome` many times: +Sebagai contoh, kita dapat membuat sebuah komponen `App` yang mencetak `Welcome` +berkali-kali. ```js{8-10} function Welcome(props) { - return

Hello, {props.name}

; + return

Halo, {props.name}

; } function App() { @@ -120,13 +135,16 @@ ReactDOM.render( [](codepen://components-and-props/composing-components) -Typically, new React apps have a single `App` component at the very top. However, if you integrate React into an existing app, you might start bottom-up with a small component like `Button` and gradually work your way to the top of the view hierarchy. +Secara khusus, aplikasi React yang baru mempunyai sebuah komponen `App` pada +bagian paling atas. Namun, jika Anda mengintegrasi React kedalam aplikasi yang +ada, Anda mungkin akan memulai secara *bottom-up* dengan komponen yang kecil +seperti `Button` dan secara bertahap kedalam hierarki paling atas. -## Extracting Components {#extracting-components} +## Mengekstraksi Komponen {#extracting-components} -Don't be afraid to split components into smaller components. +Jangan ragu untuk memisahkan komponen ke dalam bentuk yang lebih kecil. -For example, consider this `Comment` component: +Sebagai contoh, pertimbangkan komponen `Comment` berikut ini: ```js function Comment(props) { @@ -154,11 +172,15 @@ function Comment(props) { [](codepen://components-and-props/extracting-components) -It accepts `author` (an object), `text` (a string), and `date` (a date) as props, and describes a comment on a social media website. +Komponen menerima `author` (sebuah objek), `text` (sebuah string), dan `date` +(sebuah tanggal) sebagai *props*, dan mendeskripsikan sebuah komponen dalam +situs media sosial. -This component can be tricky to change because of all the nesting, and it is also hard to reuse individual parts of it. Let's extract a few components from it. +Komponen ini sedikit rumit untuk diganti karena semua berada dalam sarang, dan +itu juga sulit untuk digunakan kembali sebagai komponen pribadi. Mari +mengekstraksi beberapa komponen darinya: -First, we will extract `Avatar`: +Pertama, kita akan mengekstraksi `Avatar`: ```js{3-6} function Avatar(props) { @@ -171,11 +193,13 @@ function Avatar(props) { } ``` -The `Avatar` doesn't need to know that it is being rendered inside a `Comment`. This is why we have given its prop a more generic name: `user` rather than `author`. +`Avatar` tidak perlu tahu bahwa komponen ini di *render* di dalam sebuah +`Comment`. Ini mengapa kita harus memberikan *props* yang lebih umum seperti: `user` +daripada `author`. -We recommend naming props from the component's own point of view rather than the context in which it is being used. +Kami merekomendasikan penamaan *props* melalui sudut pandang komponen itu sendiri daripada konteks bagaimana komponen tersebut digunakan. -We can now simplify `Comment` a tiny bit: +Kita sekarang dapat sedikit menyederhanakan `Comment`: ```js{5} function Comment(props) { @@ -198,7 +222,8 @@ function Comment(props) { } ``` -Next, we will extract a `UserInfo` component that renders an `Avatar` next to the user's name: +Selanjutnya, kita akan mengekstraksi sebuah komponen `UserInfo` yang me-*render* +sebuah komponen `Avatar` di sebelah nama pengguna: ```js{3-8} function UserInfo(props) { @@ -213,7 +238,7 @@ function UserInfo(props) { } ``` -This lets us simplify `Comment` even further: +Ini memungkinkan kita untuk menyederhanakan `Comment` lebih jauh: ```js{4} function Comment(props) { @@ -233,11 +258,17 @@ function Comment(props) { [](codepen://components-and-props/extracting-components-continued) -Extracting components might seem like grunt work at first, but having a palette of reusable components pays off in larger apps. A good rule of thumb is that if a part of your UI is used several times (`Button`, `Panel`, `Avatar`), or is complex enough on its own (`App`, `FeedStory`, `Comment`), it is a good candidate to be a reusable component. +Mengekstraksi komponen mungkin terlihat seperti pekerjaan yang kasar pada +awalnya, namun mempunyai *pallete* dari komponen yang bisa digunakan kembali akan +terbayar pada aplikasi yang lebih besar. Aturan praktik yang bagus adalah jika +pada bagian dari antarmuka pengguna digunakan beberapa kali (*Button*, *Panel*, *Avatar*), atau yang cukup +kompleks (App, FeedStory, Comment), ini merupakan kandidat yang bagus untuk +dijadikan sebagai komponen yang dapat digunakan kembali. -## Props are Read-Only {#props-are-read-only} +## Props bersifat *Read-Only* {#props-are-read-only} -Whether you declare a component [as a function or a class](#function-and-class-components), it must never modify its own props. Consider this `sum` function: +Apakah Anda mendeklarasikan sebuah komponen [sebagai sebuah fungsi atau sebuah +kelas](#function-and-class-components), jangan pernah mengganti propertinya sendiri. Pertimbangkan fungsi `sum` ini: ```js function sum(a, b) { @@ -245,9 +276,12 @@ function sum(a, b) { } ``` -Such functions are called ["pure"](https://en.wikipedia.org/wiki/Pure_function) because they do not attempt to change their inputs, and always return the same result for the same inputs. +Fungsi seperti itu disebut ["*pure*"](https://en.wikipedia.org/wiki/Pure_function) +karena mereka tidak mencoba untuk mengganti masukan mereka dan selalu +mengembalikan hasil yang sama untuk setiap masukan yang sama. -In contrast, this function is impure because it changes its own input: +Sebaliknya, fungsi dibawah bukan merupakan fungsi yang murni karena hal itu telah +mengubah masukannya: ```js function withdraw(account, amount) { @@ -255,8 +289,9 @@ function withdraw(account, amount) { } ``` -React is pretty flexible but it has a single strict rule: +React sangat fleksibel namun memiliki suatu peraturan yang ketat: -**All React components must act like pure functions with respect to their props.** +**Semua komponen React harus bertindak seperti fungsi yang murni +sehubungan dengan properti mereka.** -Of course, application UIs are dynamic and change over time. In the [next section](/docs/state-and-lifecycle.html), we will introduce a new concept of "state". State allows React components to change their output over time in response to user actions, network responses, and anything else, without violating this rule. +Tentu saja, antarmuka pengguna dari aplikasi akan dinamis dan selalu berganti. Di [sesi selanjutnya](), kita akan memperkenalkan sebuah konsep baru tentang *"state"*. *State* memperbolehkan komponen React untuk mengganti keluaran mereka secara berkala untuk merespon aksi dari pengguna, respon dari jaringan, dan yang lainnya, tanpa melanggar aturan. From bb6dba75fe9c31b43547fc13ed10be49b48282bc Mon Sep 17 00:00:00 2001 From: Firmansyah Nuralif Rohman Date: Tue, 19 Mar 2019 09:14:32 +0700 Subject: [PATCH 026/152] docs:Basic - Lifting State Up (#6) * docs:basic - lifting state up * translation error * translation error #2 * resolve bad translation #3 * docs: translate strings inside codeblock --- content/docs/lifting-state-up.md | 122 +++++++++++++++---------------- 1 file changed, 61 insertions(+), 61 deletions(-) diff --git a/content/docs/lifting-state-up.md b/content/docs/lifting-state-up.md index 449330cfd..55a9a2473 100644 --- a/content/docs/lifting-state-up.md +++ b/content/docs/lifting-state-up.md @@ -1,6 +1,6 @@ --- id: lifting-state-up -title: Lifting State Up +title: Memindahkan State ke Atas permalink: docs/lifting-state-up.html prev: forms.html next: composition-vs-inheritance.html @@ -9,24 +9,24 @@ redirect_from: - "docs/flux-todo-list.html" --- -Often, several components need to reflect the same changing data. We recommend lifting the shared state up to their closest common ancestor. Let's see how this works in action. +Seringkali, beberapa komponen perlu mencerminkan perubahan data yang sama. Kami menyarankan untuk memindah `state` yang digunakan bersama tersebut ke modul _parent_ terdekat yang dimiliki komponen-komponen terkait. Mari kita lihat bagaimana ini bekerja dalam aksi. -In this section, we will create a temperature calculator that calculates whether the water would boil at a given temperature. +Di bagian ini, kita akan membuat kalkulator suhu yang menghitung apakah air akan mendidih pada suhu tertentu. -We will start with a component called `BoilingVerdict`. It accepts the `celsius` temperature as a prop, and prints whether it is enough to boil the water: +Kita akan memulai dengan komponen bernama `BoilingVerdict`. Komponen tersebut akan menerima suhu `celsius` sebagai *prop*, dan menentukan apakah suhu cukup untuk membuat air mendidih: ```js{3,5} function BoilingVerdict(props) { if (props.celsius >= 100) { - return

The water would boil.

; + return

Air akan mendidih.

; } - return

The water would not boil.

; + return

Air tidak akan mendidih.

; } ``` -Next, we will create a component called `Calculator`. It renders an `` that lets you enter the temperature, and keeps its value in `this.state.temperature`. +Selanjutnya, kita akan menampilkan komponen bernama `Calculator`. Komponen tersebut menampilkan `` yang memungkinkan Anda memasukkan suhu, dan menyimpan nilainya di `this.state.temperature`. -Additionally, it renders the `BoilingVerdict` for the current input value. +Selain itu, ini menampilkan `BoilingVerdict` untuk nilai masukan saat ini. ```js{5,9,13,17-21} class Calculator extends React.Component { @@ -56,13 +56,13 @@ class Calculator extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/ZXeOBm?editors=0010) +[**Coba di CodePen**](https://codepen.io/gaearon/pen/ZXeOBm?editors=0010) -## Adding a Second Input {#adding-a-second-input} +## Menambahkan Masukan Kedua {#adding-a-second-input} -Our new requirement is that, in addition to a Celsius input, we provide a Fahrenheit input, and they are kept in sync. +Syarat baru dari kita adalah selain masukan Celcius, kita juga memberikan masukan Fahrenheit, dan kedua masukan tersebut harus tetap sinkron. -We can start by extracting a `TemperatureInput` component from `Calculator`. We will add a new `scale` prop to it that can either be `"c"` or `"f"`: +Kita dapat memulai dengan mengeluarkan komponen `TemperatureInput` dari `Calculator`. Kita akan menambahkan *prop* `scale` baru pada komponen tersebut yang dapat bernilai `"c"` atau `"f"`: ```js{1-4,19,22} const scaleNames = { @@ -86,7 +86,7 @@ class TemperatureInput extends React.Component { const scale = this.props.scale; return (
- Enter temperature in {scaleNames[scale]}: + Masukkan temperatur dalam skala {scaleNames[scale]}:
@@ -95,7 +95,7 @@ class TemperatureInput extends React.Component { } ``` -We can now change the `Calculator` to render two separate temperature inputs: +Kita sekarang dapat mengubah `Calculator` untuk membuat dua masukan suhu terpisah: ```js{5,6} class Calculator extends React.Component { @@ -110,15 +110,15 @@ class Calculator extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/jGBryx?editors=0010) +[**Coba di CodePen**](https://codepen.io/gaearon/pen/jGBryx?editors=0010) -We have two inputs now, but when you enter the temperature in one of them, the other doesn't update. This contradicts our requirement: we want to keep them in sync. +Kita memiliki dua masukan sekarang, tetapi ketika Anda memasukkan suhu di salah satunya, yang lain tidak diperbarui. Ini bertentangan dengan syarat kita: kita ingin tetap menyinkronkannya. -We also can't display the `BoilingVerdict` from `Calculator`. The `Calculator` doesn't know the current temperature because it is hidden inside the `TemperatureInput`. +Kita juga tidak dapat menampilkan `BoilingVerdict` dari `Calculator`. `Calculator` tidak tahu suhu saat ini karena suhu tersebut tersembunyi di dalam `TemperatureInput`. -## Writing Conversion Functions {#writing-conversion-functions} +## Menulis Fungsi Konversi {#writing-conversion-functions} -First, we will write two functions to convert from Celsius to Fahrenheit and back: +Pertama, kita akan menulis dua fungsi untuk mengkonversi suhu dari Celsius ke Fahrenheit dan sebaliknya: ```js function toCelsius(fahrenheit) { @@ -130,9 +130,9 @@ function toFahrenheit(celsius) { } ``` -These two functions convert numbers. We will write another function that takes a string `temperature` and a converter function as arguments and returns a string. We will use it to calculate the value of one input based on the other input. +Dua fungsi ini akan mengkonversi angka. Kita akan menulis fungsi lain yang menggunakan fungsi *string* `temperature` dan fungsi konverter sebagai argumen dan mengembalikan string. Kita akan menggunakannya untuk menghitung nilai dari suatu masukan bersarakan masukan lainnya. -It returns an empty string on an invalid `temperature`, and it keeps the output rounded to the third decimal place: +Ini mengembalikan *string* kosong pada `temperature` yang tidak valid, dan itu membuat keluaran dibulatkan ke tempat desimal ketiga: ```js function tryConvert(temperature, convert) { @@ -146,11 +146,11 @@ function tryConvert(temperature, convert) { } ``` -For example, `tryConvert('abc', toCelsius)` returns an empty string, and `tryConvert('10.22', toFahrenheit)` returns `'50.396'`. +Misalnya, `tryConvert('abc', toCelsius)` menghasilkan *string* kosong, dan `tryConvert('10.22', toFahrenheit)` menghasilkan `'50.396'`. -## Lifting State Up {#lifting-state-up} +## Memindahkan State ke Atas {#lifting-state-up} -Currently, both `TemperatureInput` components independently keep their values in the local state: +Saat ini, kedua komponen `TemperatureInput` secara independen menyimpan nilainya di `state` lokal: ```js{5,9,13} class TemperatureInput extends React.Component { @@ -166,18 +166,18 @@ class TemperatureInput extends React.Component { render() { const temperature = this.state.temperature; - // ... + // ... ``` -However, we want these two inputs to be in sync with each other. When we update the Celsius input, the Fahrenheit input should reflect the converted temperature, and vice versa. +Namun, kita ingin kedua masukan selaras satu sama lain. Ketika kita memperbarui masukan Celcius, masukan Fahrenheit harus mencerminkan suhu yang dikonversi, dan sebaliknya. -In React, sharing state is accomplished by moving it up to the closest common ancestor of the components that need it. This is called "lifting state up". We will remove the local state from the `TemperatureInput` and move it into the `Calculator` instead. +Dalam React, *state* bersama dicapai dengan memindahkannya ke komponen induk bersama terdekat dari komponen yang membutuhkannya. Ini disebut "memindahkan *state* ke atas". Kita akan menghapus *state* lokal dari `TemperatureInput` dan memindahkannya ke `Calculator` sebagai gantinya. -If the `Calculator` owns the shared state, it becomes the "source of truth" for the current temperature in both inputs. It can instruct them both to have values that are consistent with each other. Since the props of both `TemperatureInput` components are coming from the same parent `Calculator` component, the two inputs will always be in sync. +Jika `Calculator` memiliki *state* bersama, *state* tersebut akan menjadi "sumber kebenaran" untuk suhu saat ini di kedua masukan. Ini dapat menginstruksikan kedua input untuk memiliki nilai yang konsisten satu sama lain. Karena kedua `props` pada komponen `TemperatureInput` berasal dari komponen `Calculator` induk yang sama, kedua masukan akan selalu sinkron. -Let's see how this works step by step. +Mari kita lihat bagaimana ini bekerja selangkah demi selangkah. -First, we will replace `this.state.temperature` with `this.props.temperature` in the `TemperatureInput` component. For now, let's pretend `this.props.temperature` already exists, although we will need to pass it from the `Calculator` in the future: +Pertama, kita akan ganti `this.state.temperature` dengan `this.props.temperature` di komponen `TemperatureInput`. Untuk saat ini, mari kita berpura-pura `this.props.temperature` sudah ada, meskipun kita harus menampilkannya dari `Calculator`: ```js{3} render() { @@ -186,11 +186,11 @@ First, we will replace `this.state.temperature` with `this.props.temperature` in // ... ``` -We know that [props are read-only](/docs/components-and-props.html#props-are-read-only). When the `temperature` was in the local state, the `TemperatureInput` could just call `this.setState()` to change it. However, now that the `temperature` is coming from the parent as a prop, the `TemperatureInput` has no control over it. +Kita tahu bahwa [*props* bersifat *read-only*](/docs/components-and-props.html#props-are-read-only). Ketika `temperature` berada di *state* lokal, `TemperatureInput` bisa memanggil `this.setState()` untuk mengubahnya. Namun, karena sekarang `temperature` berasal dari induknya sebagai sebuah `prop`, `TemperatureInput` tidak memiliki kendali atasnya. -In React, this is usually solved by making a component "controlled". Just like the DOM `` accepts both a `value` and an `onChange` prop, so can the custom `TemperatureInput` accept both `temperature` and `onTemperatureChange` props from its parent `Calculator`. +Dalam React, ini biasanya diselesaikan dengan membuat komponen "dikendalikan". Sama seperti *DOM* `` menerima kedua `value` dan `onChange` *prop*, begitu juga dapat menyesuaikan `TemperatureInput` menerima kedua `temperature` dan `onTemperatureChange` *props* dari `Calculator` sebagai induknya. -Now, when the `TemperatureInput` wants to update its temperature, it calls `this.props.onTemperatureChange`: +Sekarang, ketika `TemperatureInput` ingin memperbarui suhunya, ia memanggil `this.props.onTemperatureChange`: ```js{3} handleChange(e) { @@ -199,13 +199,13 @@ Now, when the `TemperatureInput` wants to update its temperature, it calls `this // ... ``` ->Note: +>Catatan: > ->There is no special meaning to either `temperature` or `onTemperatureChange` prop names in custom components. We could have called them anything else, like name them `value` and `onChange` which is a common convention. +>Tidak ada arti khusus untuk salah satu `temperature` atau `onTemperatureChange` nama *prop* dalam komponen khusus. Kita bisa memanggil mereka apapun, seperti memberi nama mereka `value` dan `onChange` yang merupakan konvensi umum. -The `onTemperatureChange` prop will be provided together with the `temperature` prop by the parent `Calculator` component. It will handle the change by modifying its own local state, thus re-rendering both inputs with the new values. We will look at the new `Calculator` implementation very soon. +*Prop* `onTemperatureChange` akan diberikan bersama-sama dengan *prop* `temperature` oleh komponen induk `Calculator`. Fungsi ini akan menangani perubahan dengan memodifikasi *state* lokalnya sendiri, sehingga menampilkan ulang kedua masukan dengan nilai-nilai baru. Kita akan segera melihat implementasi `Calculator` yang baru. -Before diving into the changes in the `Calculator`, let's recap our changes to the `TemperatureInput` component. We have removed the local state from it, and instead of reading `this.state.temperature`, we now read `this.props.temperature`. Instead of calling `this.setState()` when we want to make a change, we now call `this.props.onTemperatureChange()`, which will be provided by the `Calculator`: +Sebelum melihat perubahan di `Calculator`, mari kita rekap perubahan kita ke komponen `TemperatureInput`. Kita telah menghapus *state* lokal darinya, dan alih-alih membaca `this.state.temperature`, kita sekarang membaca `this.props.temperature`. Alih-alih memanggil `this.setState()` saat kita ingin melakukan perubahan, kita sekarang memanggil `this.props.onTemperatureChange()`, yang akan disediakan oleh `Calculator`: ```js{8,12} class TemperatureInput extends React.Component { @@ -223,7 +223,7 @@ class TemperatureInput extends React.Component { const scale = this.props.scale; return (
- Enter temperature in {scaleNames[scale]}: + Masukkan temperatur dalam skala {scaleNames[scale]}:
@@ -232,11 +232,11 @@ class TemperatureInput extends React.Component { } ``` -Now let's turn to the `Calculator` component. +Sekarang mari kita beralih ke komponen `Calculator`. -We will store the current input's `temperature` and `scale` in its local state. This is the state we "lifted up" from the inputs, and it will serve as the "source of truth" for both of them. It is the minimal representation of all the data we need to know in order to render both inputs. +Kita akan menyimpan masukan `temperature` saat ini dan `scale` dalam *state* lokal. Ini adalah kondisi yang kita "angkat" dari masukan, dan itu akan berfungsi sebagai "sumber kebenaran" untuk keduanya. Ini adalah representasi minimal dari semua data yang perlu kita ketahui untuk membuat kedua masukan. -For example, if we enter 37 into the Celsius input, the state of the `Calculator` component will be: +Misalnya, jika kita memasukkan 37 ke dalam masukan Celcius, *state* pada komponen `Calculator` akan menjadi: ```js { @@ -245,7 +245,7 @@ For example, if we enter 37 into the Celsius input, the state of the `Calculator } ``` -If we later edit the Fahrenheit field to be 212, the state of the `Calculator` will be: +Jika nanti kita mengubah kolom Fahrenheit menjadi 212, state pada `Calculator` akan menjadi: ```js { @@ -254,9 +254,9 @@ If we later edit the Fahrenheit field to be 212, the state of the `Calculator` w } ``` -We could have stored the value of both inputs but it turns out to be unnecessary. It is enough to store the value of the most recently changed input, and the scale that it represents. We can then infer the value of the other input based on the current `temperature` and `scale` alone. +Kita bisa menyimpan nilai dari kedua masukan tetapi tidak perlu. Cukup untuk menyimpan nilai masukan yang terakhir diubuah, dan skala yang diwakilinya. Kita kemudian dapat menyimpulkan nilai masukan lain berdasarkan alur `temperature` dan `scale` sendiri. -The inputs stay in sync because their values are computed from the same state: +Masukan tetap sinkron karena nilainya dihitung dari *state* yang sama: ```js{6,10,14,18-21,27-28,31-32,34} class Calculator extends React.Component { @@ -299,32 +299,32 @@ class Calculator extends React.Component { } ``` -[**Try it on CodePen**](https://codepen.io/gaearon/pen/WZpxpz?editors=0010) +[**Coba di CodePen**](https://codepen.io/gaearon/pen/WZpxpz?editors=0010) -Now, no matter which input you edit, `this.state.temperature` and `this.state.scale` in the `Calculator` get updated. One of the inputs gets the value as is, so any user input is preserved, and the other input value is always recalculated based on it. +Sekarang, tidak peduli apabila masukan berubah, `this.state.temperature` dan `this.state.scale` dalam `Calculator` akan diperbarui. Salah satu masukan mendapatkan nilai apa adanya, sehingga setiap masukan pengguna dipertahankan, dan nilai masukan lainnya selalu dihitung ulang berdasarkan masukan. -Let's recap what happens when you edit an input: +Mari kita rekap apa yang terjadi ketika Anda mengubah masukan: -* React calls the function specified as `onChange` on the DOM ``. In our case, this is the `handleChange` method in the `TemperatureInput` component. -* The `handleChange` method in the `TemperatureInput` component calls `this.props.onTemperatureChange()` with the new desired value. Its props, including `onTemperatureChange`, were provided by its parent component, the `Calculator`. -* When it previously rendered, the `Calculator` has specified that `onTemperatureChange` of the Celsius `TemperatureInput` is the `Calculator`'s `handleCelsiusChange` method, and `onTemperatureChange` of the Fahrenheit `TemperatureInput` is the `Calculator`'s `handleFahrenheitChange` method. So either of these two `Calculator` methods gets called depending on which input we edited. -* Inside these methods, the `Calculator` component asks React to re-render itself by calling `this.setState()` with the new input value and the current scale of the input we just edited. -* React calls the `Calculator` component's `render` method to learn what the UI should look like. The values of both inputs are recomputed based on the current temperature and the active scale. The temperature conversion is performed here. -* React calls the `render` methods of the individual `TemperatureInput` components with their new props specified by the `Calculator`. It learns what their UI should look like. -* React calls the `render` method of the `BoilingVerdict` component, passing the temperature in Celsius as its props. -* React DOM updates the DOM with the boiling verdict and to match the desired input values. The input we just edited receives its current value, and the other input is updated to the temperature after conversion. +* React memanggil fungsi yang disebut `onChange` pada DOM ``. Dalam kasus kita, ini adalah metode `handleChange` dalam komponen `TemperatureInput`. +* Metode `handleChange` dalam komponen `TemperatureInput` memanggil `this.props.onTemperatureChange()` dengan nilai baru. Itu merupakan *props*, termasuk `onTemperatureChange`, disediakan oleh komponen induknya, `Calculator`. +* Ketika sebelumnya di-*render*, `Calculator` telah menentukan bahwa `onTemperatureChange` dari `TemperatureInput` Celcius adalah metode `handleCelsiusChange` milik `Calculator`, dan `onTemperatureChange` dari `TemperatureInput` Fahrenheit adalah metode `handleFahrenheitChange` milik `Calculator`. Jadi salah satu dari dua metode `Calculator` dipanggil tergantung pada masukan yang kita ubah. +* Di dalam metode ini, komponen `Calculator` meminta React untuk mengulang *render* dengan memanggil `this.setState()` dengan nilai masukan baru dan skala masukan saat ini yang baru saja kita ubah. +* React memanggil komponen `Calculator` metode `render` untuk mempelajari seperti apa tampilan antarmuka pengguna. Nilai kedua masukan dihitung berdasarkan suhu saat ini dan skala aktif. Konversi suhu dilakukan di sini. +* React memanggil metode `render` pada komponen `TemperatureInput` individual dengan *props* baru yang ditentukan oleh `Calculator`. Mreka kemduain mempelajari seperti apa tampilan antarmuka pengguna mereka. +* React memanggil metode `render` pada komponen `BoilingVerdict`, melewati suhu dalam Celcius sebagai *props*. +* React DOM memperbarui dengan vonis didih dan untuk mencocokan nilai masukan yang diinginkan. Masukan yang baru saja kita ubah menerima nilainya saat ini, dan masukan lainnya diperbarui ke suhu setelah konversi. -Every update goes through the same steps so the inputs stay in sync. +Setiap pembaruan melewati langkah yang sama sehingga masukan tetap sinkron. -## Lessons Learned {#lessons-learned} +## Pelajaran yang Dipetik {#lessons-learned} -There should be a single "source of truth" for any data that changes in a React application. Usually, the state is first added to the component that needs it for rendering. Then, if other components also need it, you can lift it up to their closest common ancestor. Instead of trying to sync the state between different components, you should rely on the [top-down data flow](/docs/state-and-lifecycle.html#the-data-flows-down). +Seharusnya ada "sumber kebenaran" tunggal untuk setiap data yang berubah dalam aplikasi React. Biasanya, *state* ditambahkan pertama kali ke komponen yang membutuhkannya untuk di-*render*. Kemudian, jika komponen lain juga membutuhkannya, Anda dapat memindahkan *state* ke komponen induk bersama terdekat. Alih-alih mencoba menyinkronkan *state* antara komponen yang berbeda, Anda harus mengandalkan [aliran data dari atas kebawah](/docs/state-and-lifecycle.html#the-data-flows-down). -Lifting state involves writing more "boilerplate" code than two-way binding approaches, but as a benefit, it takes less work to find and isolate bugs. Since any state "lives" in some component and that component alone can change it, the surface area for bugs is greatly reduced. Additionally, you can implement any custom logic to reject or transform user input. +Pengangkatan *state* melibatkan penulisan lebih banyak kode "*boilerplate*" daripada pendekatan pengikatan dua arah, tetapi sebagai manfaat, dibutuhkan lebih sedikit pekerjaan untuk menemukan dan mengisolasi *bug*. Karena tiap *state* akan "hidup" di sebuah komponen dan hanya komponen itu sendiri yang dapat mengubahnya, area permukaan untuk *bug* akan sangat berkurang. Selain itu, Anda dapat menerapkan logika khusus apa pun untuk menolak atau mengubah masukan pengguna. -If something can be derived from either props or state, it probably shouldn't be in the state. For example, instead of storing both `celsiusValue` and `fahrenheitValue`, we store just the last edited `temperature` and its `scale`. The value of the other input can always be calculated from them in the `render()` method. This lets us clear or apply rounding to the other field without losing any precision in the user input. +Jika sesuatu dapat diturunkan dari *props* atau *state*, hal itu mungkin tidak sebaiknya berada di *state*. Sebagai contoh, alih-alih menyimpan keduanya `celsiusValue` dan `fahrenheitValue`, kita menyimpan hanya `temperature` yang terakhir diubah dan `scale`-nya. Nilai dari masukan lain selalu dapat dihitung dari kedua nilai tersebut dalam metode `render()`. Ini memungkinkan kita menghapus atau menerapkan pembulatan ke masukan lain tanpa kehilangan ketepatan pada masukan pengguna. -When you see something wrong in the UI, you can use [React Developer Tools](https://github.com/facebook/react-devtools) to inspect the props and move up the tree until you find the component responsible for updating the state. This lets you trace the bugs to their source: +Ketika Anda melihat sesuatu yang salah di antarmuka pengguna, Anda dapat menggunakan [Alat Pengembang React](https://github.com/facebook/react-devtools) untuk memeriksa *props* dan menelusuri *tree* komponen Anda ke atas sampai Anda menemukan komponen yang bertanggung jawab untuk memperbarui *state*. Ini memungkinkan Anda melacak *bug* ke sumbernya: Monitoring State in React DevTools From 806da34988106c2a92c9784edc2bc0e91333ca4a Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 19 Mar 2019 15:28:18 +0000 Subject: [PATCH 027/152] Add a DOM measurement recipe to Hooks FAQ (#1843) * Add a DOM measurement recipe to Hooks FAQ * Update content/docs/hooks-faq.md Co-Authored-By: gaearon * Update content/docs/hooks-faq.md Co-Authored-By: gaearon --- content/docs/hooks-faq.md | 55 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index 9016fa7f4..1e68b379c 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -41,6 +41,7 @@ This page answers some of the frequently asked questions about [Hooks](/docs/hoo * [How do I implement getDerivedStateFromProps?](#how-do-i-implement-getderivedstatefromprops) * [Is there something like forceUpdate?](#is-there-something-like-forceupdate) * [Can I make a ref to a function component?](#can-i-make-a-ref-to-a-function-component) + * [How can I measure a DOM node?](#how-can-i-measure-a-dom-node) * [What does const [thing, setThing] = useState() mean?](#what-does-const-thing-setthing--usestate-mean) * **[Performance Optimizations](#performance-optimizations)** * [Can I skip an effect on updates?](#can-i-skip-an-effect-on-updates) @@ -451,6 +452,60 @@ Try to avoid this pattern if possible. While you shouldn't need this often, you may expose some imperative methods to a parent component with the [`useImperativeHandle`](/docs/hooks-reference.html#useimperativehandle) Hook. +### How can I measure a DOM node? {#how-can-i-measure-a-dom-node} + +In order to measure the position or size of a DOM node, you can use a [callback ref](/docs/refs-and-the-dom.html#callback-refs). React will call that callback whenever the ref gets attached to a different node. Here is a [small demo](https://codesandbox.io/s/l7m0v5x4v9): + +```js{4-8,12} +function MeasureExample() { + const [height, setHeight] = useState(0); + + const measuredRef = useCallback(node => { + if (node !== null) { + setHeight(node.getBoundingClientRect().height); + } + }, []); + + return ( + <> +

Hello, world

+

The above header is {Math.round(height)}px tall

+ + ); +} +``` + +We didn't choose `useRef` in this example because an object ref doesn't notify us about *changes* to the current ref value. Using a callback ref ensures that [even if a child component displays the measured node later](https://codesandbox.io/s/818zzk8m78) (e.g. in response to a click), we still get notified about it in the parent component and can update the measurements. + +Note that we pass `[]` as a dependency array to `useCallback`. This ensures that our ref callback doesn't change between the re-renders, and so React won't call it unnecessarily. + +If you want, you can [extract this logic](https://codesandbox.io/s/m5o42082xy) into a reusable Hook: + +```js{2} +function MeasureExample() { + const [rect, ref] = useClientRect(); + return ( + <> +

Hello, world

+ {rect !== null && +

The above header is {Math.round(rect.height)}px tall

+ } + + ); +} + +function useClientRect() { + const [rect, setRect] = useState(null); + const ref = useCallback(node => { + if (node !== null) { + setRect(node.getBoundingClientRect()); + } + }, []); + return [rect, ref]; +} +``` + + ### What does `const [thing, setThing] = useState()` mean? {#what-does-const-thing-setthing--usestate-mean} If you're not familiar with this syntax, check out the [explanation](/docs/hooks-state.html#tip-what-do-square-brackets-mean) in the State Hook documentation. From ac4aa6546e413bc6bdc6d8191081b739fbc6fb27 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 19 Mar 2019 17:12:44 +0000 Subject: [PATCH 028/152] Add more explanations to Hooks API page (#1845) * Add more explanations to API page * static * add info about useLayoutEffect * Update content/docs/hooks-reference.md Co-Authored-By: gaearon * nits * nit --- content/docs/hooks-faq.md | 4 ++-- content/docs/hooks-reference.md | 39 ++++++++++++++++++++++++++++----- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/content/docs/hooks-faq.md b/content/docs/hooks-faq.md index 1e68b379c..7d2953293 100644 --- a/content/docs/hooks-faq.md +++ b/content/docs/hooks-faq.md @@ -908,7 +908,7 @@ function Form() { const [text, updateText] = useState(''); const textRef = useRef(); - useLayoutEffect(() => { + useEffect(() => { textRef.current = text; // Write it to the ref }); @@ -949,7 +949,7 @@ function useEventCallback(fn, dependencies) { throw new Error('Cannot call an event handler while rendering.'); }); - useLayoutEffect(() => { + useEffect(() => { ref.current = fn; }, [fn, ...dependencies]); diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index 4daf0f191..f2cc087d4 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -97,6 +97,8 @@ const [state, setState] = useState(() => { If you update a State Hook to the same value as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. + ### `useEffect` {#useeffect} ```js @@ -173,12 +175,24 @@ The array of dependencies is not passed as arguments to the effect function. Con ### `useContext` {#usecontext} ```js -const context = useContext(Context); +const value = useContext(MyContext); ``` -Accepts a context object (the value returned from `React.createContext`) and returns the current context value, as given by the nearest context provider for the given context. +Accepts a context object (the value returned from `React.createContext`) and returns the current context value for that context. The current context value is determined by the `value` prop of the nearest `` above the calling component in the tree. + +When the nearest `` above the component updates, this Hook will trigger a rerender with the latest context `value` passed to that `MyContext` provider. -When the provider updates, this Hook will trigger a rerender with the latest context value. +Don't forget that the argument to `useContext` must be the *context object itself*: + + * **Correct:** `useContext(MyContext)` + * **Incorrect:** `useContext(MyContext.Consumer)` + * **Incorrect:** `useContext(MyContext.Provider)` + +>Tip +> +>If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to ``. +> +>`useContext(MyContext)` only lets you *read* the context and subscribe to its changes. You still need a `` above in the tree to *provide* the value for this context. ## Additional Hooks {#additional-hooks} @@ -285,6 +299,8 @@ function Counter({initialCount}) { If you return the same value from a Reducer Hook as the current state, React will bail out without rendering the children or firing effects. (React uses the [`Object.is` comparison algorithm](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#Description).) +Note that React may still need to render that specific component again before bailing out. That shouldn't be a concern because React won't unnecessarily go "deeper" into the tree. If you're doing expensive calculations while rendering, you can optimize them with `useMemo`. + ### `useCallback` {#usecallback} ```js @@ -356,7 +372,16 @@ function TextInputWithFocusButton() { } ``` -Note that `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. +Essentially, `useRef` is like a "box" that can hold a mutable value in its `.current` property. + +You might be familiar with refs primarily as a way to [access the DOM](/docs/refs-and-the-dom.html). If you pass a ref object to React with `
`, React will set its `.current` property to the corresponding DOM node whenever that node changes. + +However, `useRef()` is useful for more than the `ref` attribute. It's [handy for keeping any mutable value around](/docs/hooks-faq.html#is-there-something-like-instance-variables) similar to how you'd use instance fields in classes. + +This works because `useRef()` creates a plain JavaScript object. The only difference between `useRef()` and creating a `{current: ...}` object yourself is that `useRef` will give you the same ref object on every render. + +Keep in mind that `useRef` *doesn't* notify you when its content changes. Mutating the `.current` property doesn't cause a re-render. If you want to run some code when React attaches or detaches a ref to a DOM node, you may want to use a [callback ref](/docs/hooks-faq.html#how-can-i-measure-a-dom-node) instead. + ### `useImperativeHandle` {#useimperativehandle} @@ -389,7 +414,11 @@ Prefer the standard `useEffect` when possible to avoid blocking visual updates. > Tip > -> If you're migrating code from a class component, `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`, so if you're unsure of which effect Hook to use, it's probably the least risky. +> If you're migrating code from a class component, note `useLayoutEffect` fires in the same phase as `componentDidMount` and `componentDidUpdate`. However, **we recommend starting with `useEffect` first** and only trying `useLayoutEffect` if that causes a problem. +> +>If you use server rendering, keep in mind that *neither* `useLayoutEffect` nor `useEffect` can run until the JavaScript is downloaded. This is why React warns when a server-rendered component contains `useLayoutEffect`. To fix this, either move that logic to `useEffect` (if it isn't necessary for the first render), or delay showing that component until after the client renders (if the HTML looks broken until `useLayoutEffect` runs). +> +>To exclude a component that needs layout effects from the server-rendered HTML, render it conditionally with `showChild && ` and defer showing it with `useEffect(() => { setShowChild(true); }, [])`. This way, the UI doesn't appear broken before hydration. ### `useDebugValue` {#usedebugvalue} From b1bc193dbad464f7c659b10f3f57e37e265a063e Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Tue, 19 Mar 2019 22:09:21 +0000 Subject: [PATCH 029/152] Document useContext bailout strategy (#1848) --- content/docs/hooks-reference.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index f2cc087d4..98c2e14c0 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -188,6 +188,8 @@ Don't forget that the argument to `useContext` must be the *context object itsel * **Incorrect:** `useContext(MyContext.Consumer)` * **Incorrect:** `useContext(MyContext.Provider)` +A component calling `useContext` will always re-render when the context value changes. If re-rendering the component is expensive, you can [optimize it by using memoization](https://github.com/facebook/react/issues/15156#issuecomment-474590693). + >Tip > >If you're familiar with the context API before Hooks, `useContext(MyContext)` is equivalent to `static contextType = MyContext` in a class, or to ``. From 1f2dbb7a4f531d1c9d70ae69e025eac992b37c6a Mon Sep 17 00:00:00 2001 From: Nat Alison Date: Wed, 20 Mar 2019 13:03:43 -0700 Subject: [PATCH 030/152] Update languages for Simplified Chinese completion (#1854) * Update languages for Simplified Chinese completion * Update languages.yml --- content/languages.yml | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/content/languages.yml b/content/languages.yml index 5e0958260..524c41c73 100644 --- a/content/languages.yml +++ b/content/languages.yml @@ -66,11 +66,15 @@ - name: Italian translated_name: Italiano code: it - status: 0 + status: 1 - name: Japanese translated_name: 日本語 code: ja status: 2 +- name: Georgian + translated_name: ქართული + code: ka + status: 0 - name: Central Khmer translated_name: ភាសាខ្មែរ code: km @@ -126,6 +130,7 @@ - name: Swedish translated_name: Svenska code: sv + status: 0 - name: Tamil translated_name: தமிழ் code: ta @@ -134,6 +139,10 @@ translated_name: తెలుగు code: te status: 0 +- name: Thai + translated_name: ไทย + code: th + status: 0 - name: Turkish translated_name: Türkçe code: tr @@ -157,7 +166,7 @@ - name: Simplified Chinese translated_name: 简体中文 code: zh-hans - status: 1 + status: 2 - name: Traditional Chinese translated_name: 繁體中文 code: zh-hant From e744030ad0c65bcd062b27ca1f442b1dd1c8f1dc Mon Sep 17 00:00:00 2001 From: Saransh Kataria Date: Mon, 25 Mar 2019 12:41:48 -0700 Subject: [PATCH 031/152] removed line as functions can have state now too (#1783) * removed line as functions can have state now too * removed this.setState line from docs --- content/docs/reference-glossary.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/reference-glossary.md b/content/docs/reference-glossary.md index e91fa9eef..bdf3587a5 100644 --- a/content/docs/reference-glossary.md +++ b/content/docs/reference-glossary.md @@ -122,7 +122,7 @@ class Welcome extends React.Component { A component needs `state` when some data associated with it changes over time. For example, a `Checkbox` component might need `isChecked` in its state, and a `NewsFeed` component might want to keep track of `fetchedPosts` in its state. -The most important difference between `state` and `props` is that `props` are passed from a parent component, but `state` is managed by the component itself. A component cannot change its `props`, but it can change its `state`. To do so, it must call `this.setState()`. Only components defined as classes can have state. +The most important difference between `state` and `props` is that `props` are passed from a parent component, but `state` is managed by the component itself. A component cannot change its `props`, but it can change its `state`. For each particular piece of changing data, there should be just one component that "owns" it in its state. Don't try to synchronize states of two different components. Instead, [lift it up](/docs/lifting-state-up.html) to their closest shared ancestor, and pass it down as props to both of them. From ee4188ba072e349ea04a4884ffc08e65ae0c2b57 Mon Sep 17 00:00:00 2001 From: Jenn Creighton Date: Mon, 25 Mar 2019 17:07:34 -0400 Subject: [PATCH 032/152] remove ReactWeek from Conference list (#1864) --- content/community/conferences.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/content/community/conferences.md b/content/community/conferences.md index ea8613c78..833e44c40 100644 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -52,11 +52,6 @@ June 21, 2019 Chicago, Illinois USA [Website](https://reactloop.com) - [Twitter](https://twitter.com/ReactLoop) -### React Week '19 {#RWNY19} -July 15-21, 2019. New York City, USA - -[Website](https://reactweek.nyc) - [Twitter](https://twitter.com/ReactWeek) - ### React Rally 2019 August 22-23, 2019. Salt Lake City, USA. From 448b7f1a2093011279227ca2e5189e4b9228c306 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Mon, 25 Mar 2019 22:49:13 -0700 Subject: [PATCH 033/152] Remove ReactNYC meetup from the list --- content/community/meetups.md | 1 - 1 file changed, 1 deletion(-) diff --git a/content/community/meetups.md b/content/community/meetups.md index d397a4535..b3f099c81 100644 --- a/content/community/meetups.md +++ b/content/community/meetups.md @@ -130,7 +130,6 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet * [New York, NY - ReactJS](https://www.meetup.com/NYC-Javascript-React-Group/) * [New York, NY - React Ladies](https://www.meetup.com/React-Ladies/) * [New York, NY - React Native](https://www.meetup.com/React-Native-NYC/) -* [New York, NY - ReactNYC](https://www.meetup.com/ReactNYC/) * [Palo Alto, CA - React Native](https://www.meetup.com/React-Native-Silicon-Valley/) * [Phoenix, AZ - ReactJS](https://www.meetup.com/ReactJS-Phoenix/) * [Pittsburgh, PA - ReactJS/React Native](https://www.meetup.com/ReactPgh/) From a1a7ec3a04617ba00de6169a35a7cb4f84811935 Mon Sep 17 00:00:00 2001 From: pixelyunicorn Date: Mon, 25 Mar 2019 22:56:24 -0700 Subject: [PATCH 034/152] Added RQ React meetup in Philadelphia (#1866) --- content/community/meetups.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/community/meetups.md b/content/community/meetups.md index b3f099c81..4c18b1311 100644 --- a/content/community/meetups.md +++ b/content/community/meetups.md @@ -131,6 +131,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet * [New York, NY - React Ladies](https://www.meetup.com/React-Ladies/) * [New York, NY - React Native](https://www.meetup.com/React-Native-NYC/) * [Palo Alto, CA - React Native](https://www.meetup.com/React-Native-Silicon-Valley/) +* [Philadelphia, PA - ReactJS](https://www.meetup.com/RQ-React/) * [Phoenix, AZ - ReactJS](https://www.meetup.com/ReactJS-Phoenix/) * [Pittsburgh, PA - ReactJS/React Native](https://www.meetup.com/ReactPgh/) * [Portland, OR - ReactJS](https://www.meetup.com/Portland-ReactJS/) From 6faeeb809f4f27a34575f881038042f4dd97ef54 Mon Sep 17 00:00:00 2001 From: pavan Date: Tue, 26 Mar 2019 11:28:15 +0530 Subject: [PATCH 035/152] Adding immer in the list of immutable libraries (#1839) * Adding immer in the list of immutable libraries * Update optimizing-performance.md --- content/docs/optimizing-performance.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/optimizing-performance.md b/content/docs/optimizing-performance.md index e42bad7b7..959332976 100644 --- a/content/docs/optimizing-performance.md +++ b/content/docs/optimizing-performance.md @@ -430,6 +430,6 @@ x === z; // true In this case, since a new reference is returned when mutating `x`, we can use a reference equality check `(x === y)` to verify that the new value stored in `y` is different than the original value stored in `x`. -Two other libraries that can help use immutable data are [seamless-immutable](https://github.com/rtfeldman/seamless-immutable) and [immutability-helper](https://github.com/kolodny/immutability-helper). +Other libraries that can help use immutable data include [Immer](https://github.com/mweststrate/immer), [immutability-helper](https://github.com/kolodny/immutability-helper), and [seamless-immutable](https://github.com/rtfeldman/seamless-immutable). Immutable data structures provide you with a cheap way to track changes on objects, which is all we need to implement `shouldComponentUpdate`. This can often provide you with a nice performance boost. From 2304fa1a7c34b719c10cca1023003e22bf0fd137 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ahmad=20Awais=20=E2=9A=A1=EF=B8=8F?= Date: Wed, 27 Mar 2019 00:36:15 +0500 Subject: [PATCH 036/152] =?UTF-8?q?=F0=9F=93=A6=20NEW:=20Add=20React.js=20?= =?UTF-8?q?Lahore=20Meetup=20Group=20(#1873)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This PR adds a relatively new sub-meetup-group of a Cloud Developers meetup group in the city of Lahore. --- content/community/meetups.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/community/meetups.md b/content/community/meetups.md index 4c18b1311..8bd1155d0 100644 --- a/content/community/meetups.md +++ b/content/community/meetups.md @@ -88,6 +88,7 @@ Do you have a local React.js meetup? Add it here! (Please keep the list alphabet ## Pakistan {#pakistan} * [Karachi](https://www.facebook.com/groups/902678696597634/) +* [Lahore](https://www.facebook.com/groups/ReactjsLahore/) ## Peru {#peru} * [Lima](https://www.meetup.com/ReactJS-Peru/) From 4541a8ff10f7f95ce1fdde1fbb9ae9280ec30b43 Mon Sep 17 00:00:00 2001 From: Nat Alison Date: Wed, 27 Mar 2019 19:15:43 -0700 Subject: [PATCH 037/152] Update languages.yml --- content/languages.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/languages.yml b/content/languages.yml index 524c41c73..1660cecb7 100644 --- a/content/languages.yml +++ b/content/languages.yml @@ -146,7 +146,7 @@ - name: Turkish translated_name: Türkçe code: tr - status: 1 + status: 2 - name: Ukrainian translated_name: Українська code: uk From c6f99a6d9a7d69138a5ea243b3b83cab710f7769 Mon Sep 17 00:00:00 2001 From: Nat Alison Date: Wed, 27 Mar 2019 19:16:47 -0700 Subject: [PATCH 038/152] Add kannada to languages --- content/languages.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/content/languages.yml b/content/languages.yml index 1660cecb7..844607526 100644 --- a/content/languages.yml +++ b/content/languages.yml @@ -79,6 +79,10 @@ translated_name: ភាសាខ្មែរ code: km status: 0 +- name: Kannada + translated_name: ಕನ್ನಡ + code: kn + status: 0 - name: Korean translated_name: 한국어 code: ko From 2753191ee2a4fa9a1ecd13fb62aac2a975d9c749 Mon Sep 17 00:00:00 2001 From: Dan Abramov Date: Thu, 28 Mar 2019 00:17:49 -0700 Subject: [PATCH 039/152] Bump React versions --- package.json | 4 ++-- src/site-constants.js | 2 +- yarn.lock | 28 ++++++++++++++-------------- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/package.json b/package.json index f1628e72e..3e255133b 100644 --- a/package.json +++ b/package.json @@ -46,8 +46,8 @@ "normalize.css": "^8.0.0", "prettier": "^1.7.4", "prismjs": "^1.15.0", - "react": "16.8.3", - "react-dom": "16.8.3", + "react": "16.8.6", + "react-dom": "16.8.6", "react-helmet": "^5.2.0", "react-live": "1.8.0-0", "remarkable": "^1.7.1", diff --git a/src/site-constants.js b/src/site-constants.js index f26103279..4618432e0 100644 --- a/src/site-constants.js +++ b/src/site-constants.js @@ -8,7 +8,7 @@ // NOTE: We can't just use `location.toString()` because when we are rendering // the SSR part in node.js we won't have a proper location. const urlRoot = 'https://reactjs.org'; -const version = '16.8.4'; +const version = '16.8.6'; const babelURL = 'https://unpkg.com/babel-standalone@6.26.0/babel.min.js'; export {babelURL, urlRoot, version}; diff --git a/yarn.lock b/yarn.lock index a3859f100..246285339 100644 --- a/yarn.lock +++ b/yarn.lock @@ -10220,15 +10220,15 @@ react-dev-utils@^4.2.1: strip-ansi "3.0.1" text-table "0.2.0" -react-dom@16.8.3: - version "16.8.3" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.3.tgz#ae236029e66210783ac81999d3015dfc475b9c32" - integrity sha512-ttMem9yJL4/lpItZAQ2NTFAbV7frotHk5DZEHXUOws2rMmrsvh1Na7ThGT0dTzUIl6pqTOi5tYREfL8AEna3lA== +react-dom@16.8.6: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.8.6.tgz#71d6303f631e8b0097f56165ef608f051ff6e10f" + integrity sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.3" + scheduler "^0.13.6" react-error-overlay@^3.0.0: version "3.0.0" @@ -10282,15 +10282,15 @@ react-side-effect@^1.1.0: exenv "^1.2.1" shallowequal "^1.0.1" -react@16.8.3: - version "16.8.3" - resolved "https://registry.yarnpkg.com/react/-/react-16.8.3.tgz#c6f988a2ce895375de216edcfaedd6b9a76451d9" - integrity sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA== +react@16.8.6: + version "16.8.6" + resolved "https://registry.yarnpkg.com/react/-/react-16.8.6.tgz#ad6c3a9614fd3a4e9ef51117f54d888da01f2bbe" + integrity sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.13.3" + scheduler "^0.13.6" read-all-stream@^3.0.0: version "3.1.0" @@ -10964,10 +10964,10 @@ sax@>=0.6.0, sax@^1.2.4, sax@~1.2.1, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.13.3: - version "0.13.3" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.3.tgz#bed3c5850f62ea9c716a4d781f9daeb9b2a58896" - integrity sha512-UxN5QRYWtpR1egNWzJcVLk8jlegxAugswQc984lD3kU7NuobsO37/sRfbpTdBjtnD5TBNFA2Q2oLV5+UmPSmEQ== +scheduler@^0.13.6: + version "0.13.6" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.6.tgz#466a4ec332467b31a91b9bf74e5347072e4cd889" + integrity sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" From d0f2db967a38e358bd59c65e981862cdf38f3d0b Mon Sep 17 00:00:00 2001 From: Saransh Kataria Date: Thu, 28 Mar 2019 15:51:37 -0700 Subject: [PATCH 040/152] removed sentence since functions can have state (#1878) With introduction of hooks, that statement is not valid anymore --- content/docs/state-and-lifecycle.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/content/docs/state-and-lifecycle.md b/content/docs/state-and-lifecycle.md index cbd8f684a..3967ae7c9 100644 --- a/content/docs/state-and-lifecycle.md +++ b/content/docs/state-and-lifecycle.md @@ -72,8 +72,6 @@ To implement this, we need to add "state" to the `Clock` component. State is similar to props, but it is private and fully controlled by the component. -We [mentioned before](/docs/components-and-props.html#functional-and-class-components) that components defined as classes have some additional features. Local state is exactly that: a feature available only to classes. - ## Converting a Function to a Class {#converting-a-function-to-a-class} You can convert a function component like `Clock` to a class in five steps: From 59c3c0a1551841cedfc8478524808492289e61f5 Mon Sep 17 00:00:00 2001 From: Wojtek Date: Fri, 29 Mar 2019 20:05:00 +0100 Subject: [PATCH 041/152] Fix explanation of the `useState` example in 'Hooks API Reference' page (#1881) --- content/docs/hooks-reference.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/docs/hooks-reference.md b/content/docs/hooks-reference.md index 98c2e14c0..24145eac2 100644 --- a/content/docs/hooks-reference.md +++ b/content/docs/hooks-reference.md @@ -67,7 +67,7 @@ function Counter({initialCount}) { } ``` -The "+" and "-" buttons use the functional form, because the updated value is based on the previous value. But the "Reset" button uses the normal form, because it always sets the count back to 0. +The "+" and "-" buttons use the functional form, because the updated value is based on the previous value. But the "Reset" button uses the normal form, because it always sets the count back to the initial value. > Note > From 8de5aff111bba0f04ff254aad1a084a2b2f48743 Mon Sep 17 00:00:00 2001 From: Nat Alison Date: Mon, 1 Apr 2019 23:53:19 -0700 Subject: [PATCH 042/152] Update languages.yml to show italian finishing --- content/languages.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/languages.yml b/content/languages.yml index 844607526..a7fe36f1f 100644 --- a/content/languages.yml +++ b/content/languages.yml @@ -66,7 +66,7 @@ - name: Italian translated_name: Italiano code: it - status: 1 + status: 2 - name: Japanese translated_name: 日本語 code: ja @@ -174,4 +174,4 @@ - name: Traditional Chinese translated_name: 繁體中文 code: zh-hant - status: 0 + status: 1 From c7dde3d237489c86afacc0df62e6b9b1055e023e Mon Sep 17 00:00:00 2001 From: Parker Bond Date: Wed, 3 Apr 2019 13:31:06 -0600 Subject: [PATCH 043/152] Add Chain React to conferences list (#1900) Chain React is a React Native focused conference put on yearly. This will be the 3rd year it has been held. --- content/community/conferences.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/content/community/conferences.md b/content/community/conferences.md index 833e44c40..0c94b6c2a 100644 --- a/content/community/conferences.md +++ b/content/community/conferences.md @@ -52,6 +52,11 @@ June 21, 2019 Chicago, Illinois USA [Website](https://reactloop.com) - [Twitter](https://twitter.com/ReactLoop) +### Chain React 2019 +July 11-12, 2019. Portland, OR, USA. + +[Website](https://infinite.red/ChainReactConf) + ### React Rally 2019 August 22-23, 2019. Salt Lake City, USA. @@ -59,6 +64,7 @@ August 22-23, 2019. Salt Lake City, USA. ### ComponentsConf 2019 {#componentsconf-2019} September 6, 2019 in Melbourne, Australia + [Website](https://www.componentsconf.com.au/) - [Twitter](https://twitter.com/componentsconf) ### React Native EU 2019 {#react-native-eu-2019} From 2a1b08943c2c65bbf5a6a1e63777488833909f45 Mon Sep 17 00:00:00 2001 From: Camilo Giraldo Date: Wed, 3 Apr 2019 14:51:42 -0500 Subject: [PATCH 044/152] Fix 1640: Formatting for code blocks nested in blockquote (#1899) --- src/theme.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/theme.js b/src/theme.js index a4d445206..8d0c2735f 100644 --- a/src/theme.js +++ b/src/theme.js @@ -405,6 +405,10 @@ const sharedStyles = { marginTop: 0, }, }, + + '& .gatsby-highlight': { + marginLeft: 0, + }, }, '& .gatsby-highlight + blockquote': { From 24f9dcb866459ae96b70af8a9fb30f71bfc66c2c Mon Sep 17 00:00:00 2001 From: riftsplitter Date: Fri, 12 Apr 2019 19:35:42 +0700 Subject: [PATCH 045/152] added translation on reactdomserver page (#29) * added translation on reactdomserver page * fixed some of the words and capitalization according to suggested changes * updated docs according to suggestion --- content/docs/reference-react-dom-server.md | 50 +++++++++++----------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/content/docs/reference-react-dom-server.md b/content/docs/reference-react-dom-server.md index 80c030377..fef0c0df4 100644 --- a/content/docs/reference-react-dom-server.md +++ b/content/docs/reference-react-dom-server.md @@ -6,7 +6,7 @@ category: Reference permalink: docs/react-dom-server.html --- -The `ReactDOMServer` object enables you to render components to static markup. Typically, it's used on a Node server: +Objek `ReactDOMServer` memungkinkan Anda untuk me-*render* komponen-komponen ke dalam bentuk *markup* statis. Objek ini digunakan di dalam server Node : ```js // ES modules @@ -15,78 +15,76 @@ import ReactDOMServer from 'react-dom/server'; var ReactDOMServer = require('react-dom/server'); ``` -## Overview {#overview} +## Ikthisar {#overview} -The following methods can be used in both the server and browser environments: +*Method-method* di bawah ini bisa digunakan di dalam ruang lingkup server dan *browser* : - [`renderToString()`](#rendertostring) - [`renderToStaticMarkup()`](#rendertostaticmarkup) -These additional methods depend on a package (`stream`) that is **only available on the server**, and won't work in the browser. +*Method-method* tambahan ini bergantung pada *package* (`stream`) yang hanya **tersedia di server**, dan tidak dapat bekerja di dalam *browser*. - [`renderToNodeStream()`](#rendertonodestream) - [`renderToStaticNodeStream()`](#rendertostaticnodestream) * * * -## Reference {#reference} +## Referensi {#reference} ### `renderToString()` {#rendertostring} ```javascript -ReactDOMServer.renderToString(element) +ReactDOMServer.renderToString(elemen) ``` -Render a React element to its initial HTML. React will return an HTML string. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes. +Me-*render* sebuah elemen React menjadi HTML biasa. React akan mengembalikan sebuah *string* HTML. Anda bisa menggunakan *method* ini untuk menghasilkan HTML di server dan mengirim *markup* pada permintaan pertama untuk pemuatan halaman yang lebih cepat dan juga memungkinkan mesin pencarian untuk melakukan *crawling* pada halaman-halaman Anda demi kepentingan SEO. -If you call [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience. +Jika Anda memanggil [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) di dalam sebuah *node* yang sudah memiliki *markup* yang merupakan hasil dari *render* di server, React akan menyimpan *markup* tersebut dan hanya memasang *event handler* pada *markup* tersebut, memungkinkan Anda untuk mendapat performa *first-load experience* yang sangat bagus. * * * ### `renderToStaticMarkup()` {#rendertostaticmarkup} ```javascript -ReactDOMServer.renderToStaticMarkup(element) +ReactDOMServer.renderToStaticMarkup(elemen) ``` -Similar to [`renderToString`](#rendertostring), except this doesn't create extra DOM attributes that React uses internally, such as `data-reactroot`. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save some bytes. +Sama seperti [`renderToString`](#rendertostring), bedanya *method* ini tidak membuat atribut DOM tambahan yang digunakan React secara internal, seperti `data-reactroot`. Metode ini bermanfaat jika Anda ingin menggunakan React untuk menghasilkan halaman statis yang simpel, dikarenakan menghapus beberapa atribut tambahan bisa menghemat beberapa *byte*. -If you plan to use React on the client to make the markup interactive, do not use this method. Instead, use [`renderToString`](#rendertostring) on the server and [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) on the client. +Jika Anda berencana untuk menggunakan React di sisi klien untuk membuat *markup* yang interaktif, Anda tidak disarankan untuk menggunakan *method* ini. Sebaiknya, gunakan [`renderToString`](#rendertostring) di sisi server dan gunakan [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) di sisi klien. * * * ### `renderToNodeStream()` {#rendertonodestream} ```javascript -ReactDOMServer.renderToNodeStream(element) +ReactDOMServer.renderToNodeStream(elemen) ``` -Render a React element to its initial HTML. Returns a [Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) that outputs an HTML string. The HTML output by this stream is exactly equal to what [`ReactDOMServer.renderToString`](#rendertostring) would return. You can use this method to generate HTML on the server and send the markup down on the initial request for faster page loads and to allow search engines to crawl your pages for SEO purposes. +Me-*render* sebuah elemen React menjadi HTML biasa. Mengembalikan sebuah [Readable stream](https://nodejs.org/api/stream.html#stream_readable_streams) yang menghasilkan sebuah *string* HTML. Keluaran HTML oleh *stream* ini sama persis dengan keluaran yang dikembalikan oleh [`ReactDOMServer.renderToString`](#rendertostring). Anda dapat menggunakan *method* untuk menghasilkan HTML di server dan mengirim *markup* tersebut pada permintaan pertama untuk pemuatan halaman yang lebih cepat dan juga memungkinkan mesin pencarian untuk melakukan *crawling* pada halaman-halaman Anda demi kepentingan SEO. -If you call [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) on a node that already has this server-rendered markup, React will preserve it and only attach event handlers, allowing you to have a very performant first-load experience. +Jika Anda memanggil [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) di dalam sebuah *node* yang sudah memiliki *markup* yang merupakan hasil dari *render* di server, React akan menyimpan *markup* tersebut dan hanya memasang *event handler* pada *markup* tersebut, memungkinkan Anda untuk mendapat performa *first-load experience* yang sangat bagus. -> Note: +> Catatan: > -> Server-only. This API is not available in the browser. +> Hanya untuk server. API ini tidak bisa digunakan di *browser*. > -> The stream returned from this method will return a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text. - +> *Stream* yang dikembalikan oleh *method* ini akan mengembalikan sebuah *byte stream* yang dienkode dalam utf-8. Jika Anda membutuhkan *stream* dalam kode selain utf-8, disarankan untuk mencoba melihat proyek seperti [iconv-lite](https://www.npmjs.com/package/iconv-lite), yang menyediakan *transform streams* untuk *transcoding text*. * * * ### `renderToStaticNodeStream()` {#rendertostaticnodestream} ```javascript -ReactDOMServer.renderToStaticNodeStream(element) +ReactDOMServer.renderToStaticNodeStream(elemen) ``` -Similar to [`renderToNodeStream`](#rendertonodestream), except this doesn't create extra DOM attributes that React uses internally, such as `data-reactroot`. This is useful if you want to use React as a simple static page generator, as stripping away the extra attributes can save some bytes. - -The HTML output by this stream is exactly equal to what [`ReactDOMServer.renderToStaticMarkup`](#rendertostaticmarkup) would return. +Sama seperti [`renderToNodeStream`](#rendertonodestream), bedanya *method* ini tidak membuat atribut DOM tambahan yang digunakan React secara internal, seperti `data-reactroot`. Metode ini bermanfaat jika Anda ingin menggunakan React untuk menghasilkan halaman statis yang simpel, dikarenakan menghapus beberapa atribut tambahan bisa menghemat beberapa *byte*. +Hasil keluaran HTML yang dikembalikan oleh *stream* ini sama persis dengan yang dikembalikan oleh [`ReactDOMServer.renderToStaticMarkup`](#rendertostaticmarkup). -If you plan to use React on the client to make the markup interactive, do not use this method. Instead, use [`renderToNodeStream`](#rendertonodestream) on the server and [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) on the client. +Jika Anda berencana untuk menggunakan React di sisi klien untuk membuat *markup* yang interaktif, Anda tidak disarankan untuk menggunakan *method* ini. Sebaiknya, gunakan [`renderToString`](#rendertostring) di sisi server dan gunakan [`ReactDOM.hydrate()`](/docs/react-dom.html#hydrate) di sisi klien. -> Note: +> Catatan: > -> Server-only. This API is not available in the browser. +> Hanya untuk di server. API ini tidak bisa digunakan di *browser*. > -> The stream returned from this method will return a byte stream encoded in utf-8. If you need a stream in another encoding, take a look at a project like [iconv-lite](https://www.npmjs.com/package/iconv-lite), which provides transform streams for transcoding text. +> *Stream* yang dikembalikan oleh *method* ini akan mengembalikan sebuah *byte stream* yang dikodekan dalam utf-8. Jika Anda membutuhkan *stream* dalam kode selain kode utf-8, disarankan Anda untuk mencoba melihat projek seperti [iconv-lite](https://www.npmjs.com/package/iconv-lite), yang menyediakan *transform streams* untuk *transcoding text*. From 6902a3551b7f50e377b9a68cab62d4b0cc4e9cb9 Mon Sep 17 00:00:00 2001 From: M Nindra Zaka Date: Fri, 12 Apr 2019 20:57:00 +0700 Subject: [PATCH 046/152] translate React API Reference (#26) * translate React API Reference * correction v1 * correction v2: capitalize all 'anda' --- content/docs/reference-react.md | 164 ++++++++++++++++---------------- 1 file changed, 82 insertions(+), 82 deletions(-) diff --git a/content/docs/reference-react.md b/content/docs/reference-react.md index d506a1ad3..c7fa53a20 100644 --- a/content/docs/reference-react.md +++ b/content/docs/reference-react.md @@ -1,6 +1,6 @@ --- id: react-api -title: React Top-Level API +title: API Tingkat Atas React layout: docs category: Reference permalink: docs/react-api.html @@ -13,35 +13,35 @@ redirect_from: - "docs/top-level-api-zh-CN.html" --- -`React` is the entry point to the React library. If you load React from a ` - + ``` -The first two tags load React. The third one will load your component code. +*Tag* pertama dan kedua akan memuat React. *Tag* ketiga akan memuat kode komponen Anda. -### Step 3: Create a React Component {#step-3-create-a-react-component} -Create a file called `like_button.js` next to your HTML page. +### Langkah 3: Buat Sebuah Komponen React {#step-3-create-a-react-component} -Open **[this starter code](https://cdn.rawgit.com/gaearon/0b180827c190fe4fd98b4c7f570ea4a8/raw/b9157ce933c79a4559d2aa9ff3372668cce48de7/LikeButton.js)** and paste it into the file you created. +Buat sebuah berkas bernama `like_button.js` tepat disebelah berkas laman HTML Anda. + +Buka **[kode permulaan](https://cdn.rawgit.com/gaearon/0b180827c190fe4fd98b4c7f570ea4a8/raw/b9157ce933c79a4559d2aa9ff3372668cce48de7/LikeButton.js)** dan *paste*-kan kode tersebut ke berkas yang baru saja Anda buat. >Tip > ->This code defines a React component called `LikeButton`. Don't worry if you don't understand it yet -- we'll cover the building blocks of React later in our [hands-on tutorial](/tutorial/tutorial.html) and [main concepts guide](/docs/hello-world.html). For now, let's just get it showing on the screen! +>Kode ini mendefinisikan sebuah komponen React bernama `LikeButton`. Jangan khawatir jika Anda belum memahaminya -- kita akan membahas blok-blok pembangun React nantinya di [tutorial langsung](/tutorial/tutorial.html) dan [panduan konsep utama](/docs/hello-world.html). Untuk sekarang, mari kita fokus untuk membuatnya muncul di layar terlebih dahulu! -After **[the starter code](https://cdn.rawgit.com/gaearon/0b180827c190fe4fd98b4c7f570ea4a8/raw/b9157ce933c79a4559d2aa9ff3372668cce48de7/LikeButton.js)**, add two lines to the bottom of `like_button.js`: +Setelah **[kode permulaan](https://cdn.rawgit.com/gaearon/0b180827c190fe4fd98b4c7f570ea4a8/raw/b9157ce933c79a4559d2aa9ff3372668cce48de7/LikeButton.js)**, tambahkan dua barus di bawah berkas `like_button.js`: ```js{3,4} -// ... the starter code you pasted ... +// ... kode permulaan yang telah Anda paste ... const domContainer = document.querySelector('#like_button_container'); ReactDOM.render(e(LikeButton), domContainer); ``` -These two lines of code find the `
` we added to our HTML in the first step, and then display our "Like" button React component inside of it. +Kedua baris kode di atas akan menemukan `
` yang telah kita tambahkan ke HTML kita di langkah pertama, kemudian menampilkan komponen React tombol "Like" kita di dalamnya. -### That's It! {#thats-it} +### Itu Saja! {#thats-it} -There is no step four. **You have just added the first React component to your website.** +Tidak ada langkah ke empat. **Anda baru saja menambahkan komponen React pertama pada situs Anda** -Check out the next sections for more tips on integrating React. +Kunjungi bagian-bagian berikutnya untuk tips lebih lanjut mengenai mengintegrasikan React. -**[View the full example source code](https://gist.github.com/gaearon/6668a1f6986742109c00a581ce704605)** +**[Lihat contoh kode sumber lengkapnya](https://gist.github.com/gaearon/6668a1f6986742109c00a581ce704605)** -**[Download the full example (2KB zipped)](https://gist.github.com/gaearon/6668a1f6986742109c00a581ce704605/archive/f6c882b6ae18bde42dcf6fdb751aae93495a2275.zip)** +**[Unduh contoh lengkapnya (2KB *zipped*)](https://gist.github.com/gaearon/6668a1f6986742109c00a581ce704605/archive/f6c882b6ae18bde42dcf6fdb751aae93495a2275.zip)** -### Tip: Reuse a Component {#tip-reuse-a-component} +### Tip: Penggunaan Ulang Sebuah Komponen {#tip-reuse-a-component} -Commonly, you might want to display React components in multiple places on the HTML page. Here is an example that displays the "Like" button three times and passes some data to it: +Umumnya, Anda mungkin ingin menampilkan komponen React di berbagai tempat di laman HTML. Ini adalah sebuah contoh untuk menampilkan tombol "Like" tiga kali dan mengoperkan data ke dalamnya. -[View the full example source code](https://gist.github.com/gaearon/faa67b76a6c47adbab04f739cba7ceda) +[Lihat contoh kode sumber lengkapnya](https://gist.github.com/gaearon/faa67b76a6c47adbab04f739cba7ceda) -[Download the full example (2KB zipped)](https://gist.github.com/gaearon/faa67b76a6c47adbab04f739cba7ceda/archive/9d0dd0ee941fea05fd1357502e5aa348abb84c12.zip) +[Unduh contoh lengkapnya (2KB *zipped*)](https://gist.github.com/gaearon/faa67b76a6c47adbab04f739cba7ceda/archive/9d0dd0ee941fea05fd1357502e5aa348abb84c12.zip) ->Note +>Catatan > ->This strategy is mostly useful while React-powered parts of the page are isolated from each other. Inside React code, it's easier to use [component composition](/docs/components-and-props.html#composing-components) instead. +>Strategi ini akan lebih berguna untuk penggunaan React di bagian-bagian laman yang terisolasi satu sama lain. Di dalam kode React sendiri, akan lebih mudah menggunakan [komposisi komponen](/docs/components-and-props.html#composing-components). -### Tip: Minify JavaScript for Production {#tip-minify-javascript-for-production} +### Tip: Minifikasi JavaScript untuk Production {#tip-minify-javascript-for-production} -Before deploying your website to production, be mindful that unminified JavaScript can significantly slow down the page for your users. +Sebelum men-*deploy* situs Anda ke *production*, berhati-hatilah terhadap JavaScript yang belum diminifikasi yang dapat secara signifikan memperlambat laman untuk pengguna Anda. -If you already minify the application scripts, **your site will be production-ready** if you ensure that the deployed HTML loads the versions of React ending in `production.min.js`: +Jika Anda telah meminifikasi *script* aplikasi, **situs Anda telah siap untuk *production*** jika Anda telah memastikan HTML yang ter-*deploy* memuat versi React yang berakhiran dengan `production.min.js`: ```js ``` -If you don't have a minification step for your scripts, [here's one way to set it up](https://gist.github.com/gaearon/42a2ffa41b8319948f9be4076286e1f3). +Jika Anda belum memiliki proses minifikasi untuk *script* Anda, [berikut salah satu cara untuk mempersiapkannya](https://gist.github.com/gaearon/42a2ffa41b8319948f9be4076286e1f3). -## Optional: Try React with JSX {#optional-try-react-with-jsx} +## Opsional: Mencoba React dengan JSX {#optional-try-react-with-jsx} -In the examples above, we only relied on features that are natively supported by the browsers. This is why we used a JavaScript function call to tell React what to display: +Pada contoh di atas, kita hanya bergantung pada fitur-fitur yang secara langsung didukung oleh *browser*. Inilah alasan mengapa kita menggunakan sebuah fungsi JavaScript untuk memberitahukan React apa yang akan ditampilkan: ```js const e = React.createElement; -// Display a "Like"