From 406ffd7d3d430a5f91328e85a5475a9cfdc596c4 Mon Sep 17 00:00:00 2001 From: sagar Date: Thu, 9 Jan 2020 15:45:48 +0530 Subject: [PATCH 01/12] =?UTF-8?q?=F0=9F=93=A6=20NEW:=20useAsync=20hook=20a?= =?UTF-8?q?dd?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snippets/UseAsync.md | 72 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 snippets/UseAsync.md diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md new file mode 100644 index 000000000..5f717044a --- /dev/null +++ b/snippets/UseAsync.md @@ -0,0 +1,72 @@ +--- +title: useAsync +tags: react,intermediate,hook +--- + + +The `useAsync` hook is used to bind asynchronous call and handle different states like loading, error, and value. According to the state of an asynchronous call, we can render different states like loading, error and value state. + +**Explanation:** +In `useAsync` hook we need to pass the handler function and that will be called after calling the `run` method. Once `run` get's called we're changing loading, error and value field according to asynchronous call response. + +```js +const useAsync = (fn, options = {}) => { + const autoRun = options.autoRun || false + + const [state, setState] = React.useState({ + error: null, + loading: false, + value: null, + }) + + const handleStateChange = args => { + setState({ ...state, ...args }) + } + + const run = async (args = null) => { + try { + handleStateChange({ loading: true, error: null }) + const value = await fn(args) + handleStateChange({ loading: false, value: value || null, error: null }) + } catch (error) { + handleStateChange({ loading: false, value: null, error }) + } + } + + React.useEffect(() => { + if (autoRun) { + run() + } + }, [autoRun]) + + return { + state, + setState, + run, + } +} +``` + +**Usages** +```jsx +const App = () => { + const handleSubmit = () => { + const url = "https://jsonplaceholder.typicode.com/todos" + return fetch(url).then(response => response.json()) + } + + const submission = useAsync(handleSubmit, { autoRun: false }) + + return ( +
+ {submission.value &&
{submission.value}
} + +
+ ) +} +``` From ea39369af79df8878e37931c5635809972af5ce8 Mon Sep 17 00:00:00 2001 From: sagar Date: Thu, 9 Jan 2020 20:21:10 +0530 Subject: [PATCH 02/12] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20PR=20comments=20fix?= =?UTF-8?q?ed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snippets/UseAsync.md | 54 ++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md index 5f717044a..e4242318e 100644 --- a/snippets/UseAsync.md +++ b/snippets/UseAsync.md @@ -1,35 +1,34 @@ --- title: useAsync -tags: react,intermediate,hook +tags: hooks,state,effect,intermediate --- +A hook that handle asynchronous calls. -The `useAsync` hook is used to bind asynchronous call and handle different states like loading, error, and value. According to the state of an asynchronous call, we can render different states like loading, error and value state. +- Create a custom hook that takes a handler `function` and `options`. +- Use the `React.useState()` hook to initialize the `value`, `error` and `loading` state variables. +- Use the `React.useEffect()` hook to call `run()` method and update the state variables accordingly if `options.autoRun` set to true. +- Use the `run` function to manually trigger `handler` function. +- Return an object containting the `value`, `error` and `isLoading` state variables and `run` function. -**Explanation:** -In `useAsync` hook we need to pass the handler function and that will be called after calling the `run` method. Once `run` get's called we're changing loading, error and value field according to asynchronous call response. - -```js +```jsx const useAsync = (fn, options = {}) => { + const [value, setValue] = React.useState(null) + const [error, setError] = React.useState(null) + const [isLoading, setIsLoading] = React.useState(false) + const autoRun = options.autoRun || false - const [state, setState] = React.useState({ - error: null, - loading: false, - value: null, - }) - - const handleStateChange = args => { - setState({ ...state, ...args }) - } - const run = async (args = null) => { try { - handleStateChange({ loading: true, error: null }) + setIsLoading(true) const value = await fn(args) - handleStateChange({ loading: false, value: value || null, error: null }) + setError(null) + setValue(value) } catch (error) { - handleStateChange({ loading: false, value: null, error }) + setIsLoading(false) + setValue(null) + setError(error) } } @@ -40,17 +39,17 @@ const useAsync = (fn, options = {}) => { }, [autoRun]) return { - state, - setState, + value, + error, + isLoading, run, } } ``` -**Usages** ```jsx const App = () => { - const handleSubmit = () => { + const handleSubmit = (args) => { // args {foo: bar} const url = "https://jsonplaceholder.typicode.com/todos" return fetch(url).then(response => response.json()) } @@ -59,13 +58,10 @@ const App = () => { return (
- {submission.value &&
{submission.value}
} - +
{JSON.stringify(submission.value, null, 2)}
) } From ea559a1e668e0902e37188d6029c38bc4afa85a1 Mon Sep 17 00:00:00 2001 From: sagar Date: Thu, 9 Jan 2020 20:26:38 +0530 Subject: [PATCH 03/12] =?UTF-8?q?=F0=9F=90=9B=20FIX:?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snippets/UseAsync.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md index e4242318e..561582f2f 100644 --- a/snippets/UseAsync.md +++ b/snippets/UseAsync.md @@ -23,12 +23,13 @@ const useAsync = (fn, options = {}) => { try { setIsLoading(true) const value = await fn(args) + setIsLoading(false) setError(null) setValue(value) } catch (error) { setIsLoading(false) - setValue(null) setError(error) + setValue(null) } } From 19f41b21e2330d42c45f7e46889d61b6f640f913 Mon Sep 17 00:00:00 2001 From: sagar Date: Thu, 9 Jan 2020 20:28:00 +0530 Subject: [PATCH 04/12] isLoading set to false --- snippets/UseAsync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md index 561582f2f..4c43ace15 100644 --- a/snippets/UseAsync.md +++ b/snippets/UseAsync.md @@ -50,7 +50,7 @@ const useAsync = (fn, options = {}) => { ```jsx const App = () => { - const handleSubmit = (args) => { // args {foo: bar} + const handleSubmit = (args) => { // args { foo: bar } const url = "https://jsonplaceholder.typicode.com/todos" return fetch(url).then(response => response.json()) } From 103bb106392438ac55d1918b99a30de54abdf235 Mon Sep 17 00:00:00 2001 From: sagar Date: Thu, 9 Jan 2020 22:01:21 +0530 Subject: [PATCH 05/12] =?UTF-8?q?=F0=9F=90=9B=20FIX:=20typo=20handle=20=3D?= =?UTF-8?q?>=20handles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snippets/UseAsync.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md index 4c43ace15..9a6b2a7d3 100644 --- a/snippets/UseAsync.md +++ b/snippets/UseAsync.md @@ -3,7 +3,7 @@ title: useAsync tags: hooks,state,effect,intermediate --- -A hook that handle asynchronous calls. +A hook that handles asynchronous calls. - Create a custom hook that takes a handler `function` and `options`. - Use the `React.useState()` hook to initialize the `value`, `error` and `loading` state variables. From 80414e1f9c0f5a53bb45aeda65912b5f4df6441a Mon Sep 17 00:00:00 2001 From: sagar Date: Thu, 9 Jan 2020 22:05:12 +0530 Subject: [PATCH 06/12] =?UTF-8?q?=F0=9F=91=8C=20IMPROVE:=20semicolons=20ad?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- snippets/UseAsync.md | 56 ++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md index 9a6b2a7d3..8c3ac1416 100644 --- a/snippets/UseAsync.md +++ b/snippets/UseAsync.md @@ -13,57 +13,61 @@ A hook that handles asynchronous calls. ```jsx const useAsync = (fn, options = {}) => { - const [value, setValue] = React.useState(null) - const [error, setError] = React.useState(null) - const [isLoading, setIsLoading] = React.useState(false) + const [value, setValue] = React.useState(null); + const [error, setError] = React.useState(null); + const [isLoading, setIsLoading] = React.useState(false); - const autoRun = options.autoRun || false + const autoRun = options.autoRun || false; const run = async (args = null) => { try { - setIsLoading(true) - const value = await fn(args) - setIsLoading(false) - setError(null) - setValue(value) + setIsLoading(true); + const value = await fn(args); + setIsLoading(false); + setError(null); + setValue(value); } catch (error) { - setIsLoading(false) - setError(error) - setValue(null) + setIsLoading(false); + setError(error); + setValue(null); } - } + }; React.useEffect(() => { if (autoRun) { - run() + run(); } - }, [autoRun]) + }, [autoRun]); return { value, error, isLoading, run, - } -} + }; +}; ``` ```jsx const App = () => { - const handleSubmit = (args) => { // args { foo: bar } - const url = "https://jsonplaceholder.typicode.com/todos" - return fetch(url).then(response => response.json()) - } + const handleSubmit = args => { + // args { foo: bar } + const url = "https://jsonplaceholder.typicode.com/todos"; + return fetch(url).then(response => response.json()); + }; - const submission = useAsync(handleSubmit, { autoRun: false }) + const submission = useAsync(handleSubmit, { autoRun: false }); return (
-
{JSON.stringify(submission.value, null, 2)}
- ) -} + ); +}; ``` From 6c7529775dd0cb973c6a92ef3c6c5dba8621881e Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 9 Jan 2020 20:22:12 +0200 Subject: [PATCH 07/12] Update and rename UseAsync.md to useAsync.md --- snippets/UseAsync.md | 73 -------------------------------------------- snippets/useAsync.md | 65 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 65 insertions(+), 73 deletions(-) delete mode 100644 snippets/UseAsync.md create mode 100644 snippets/useAsync.md diff --git a/snippets/UseAsync.md b/snippets/UseAsync.md deleted file mode 100644 index 8c3ac1416..000000000 --- a/snippets/UseAsync.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: useAsync -tags: hooks,state,effect,intermediate ---- - -A hook that handles asynchronous calls. - -- Create a custom hook that takes a handler `function` and `options`. -- Use the `React.useState()` hook to initialize the `value`, `error` and `loading` state variables. -- Use the `React.useEffect()` hook to call `run()` method and update the state variables accordingly if `options.autoRun` set to true. -- Use the `run` function to manually trigger `handler` function. -- Return an object containting the `value`, `error` and `isLoading` state variables and `run` function. - -```jsx -const useAsync = (fn, options = {}) => { - const [value, setValue] = React.useState(null); - const [error, setError] = React.useState(null); - const [isLoading, setIsLoading] = React.useState(false); - - const autoRun = options.autoRun || false; - - const run = async (args = null) => { - try { - setIsLoading(true); - const value = await fn(args); - setIsLoading(false); - setError(null); - setValue(value); - } catch (error) { - setIsLoading(false); - setError(error); - setValue(null); - } - }; - - React.useEffect(() => { - if (autoRun) { - run(); - } - }, [autoRun]); - - return { - value, - error, - isLoading, - run, - }; -}; -``` - -```jsx -const App = () => { - const handleSubmit = args => { - // args { foo: bar } - const url = "https://jsonplaceholder.typicode.com/todos"; - return fetch(url).then(response => response.json()); - }; - - const submission = useAsync(handleSubmit, { autoRun: false }); - - return ( -
- -
{JSON.stringify(submission.value, null, 2)}
-
- ); -}; -``` diff --git a/snippets/useAsync.md b/snippets/useAsync.md new file mode 100644 index 000000000..9881094f3 --- /dev/null +++ b/snippets/useAsync.md @@ -0,0 +1,65 @@ +--- +title: useAsync +tags: hooks,state,reducer,advanced +--- + +A hook that handles asynchronous calls. + +- Create a custom hook that takes a handler function, `fn`. +- Define a reducer function and an initial state for the custom hook's state. +- Use the `React.useReducer()` hook to initialize the `state` variable and the `dispatch` function. +- Define a `run` function that will run the provided callback, `fn`, while using `dispatch` to update `state` as necessary. +- Return an object containting the the properties of `state` (`value`, `error` and `loading`) and the `run` function. + +```jsx +const useAsync = (fn) => { + const initialState = { loading: false, error: null, value: null }; + const stateReducer = (_, action) => { + switch (action.type) { + case 'start': + return { loading: true, error: null, value: null}; + case 'finish': + return { loading: false, error: null, value: action.value}; + case 'error': + return { loading: false, error: action.error, value: null}; + } + } + + const [state, dispatch] = React.useReducer(stateReducer, initialState); + + const run = async (args = null) => { + try { + dispatch({ type: 'start' }); + const value = await fn(args); + dispatch({ type: 'finish', value }); + } catch (error) { + dispatch({ type: 'error', error }); + } + }; + + return { ...state, run }; +}; +``` + +```jsx +const RandomImage = props => { + const imgFetch = useAsync(url => fetch(url).then(response => response.json())); + + return ( +
+ +
+ { imgFetch.loading &&
Loading...
} + { imgFetch.error &&
Error { imgFetch.error }
} + { imgFetch.value && avatar} +
+ ); +}; + +ReactDOM.render(, document.getElementById('root')); +``` From 3ec1c7e2948cc34de42c45cbade5b4259cb3dafa Mon Sep 17 00:00:00 2001 From: 30secondsofcode <30secondsofcode@gmail.com> Date: Thu, 9 Jan 2020 18:25:08 +0000 Subject: [PATCH 08/12] Travis build: 224 --- snippet_data/snippetList.json | 17 +++++++++++++++++ snippet_data/snippets.json | 27 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/snippet_data/snippetList.json b/snippet_data/snippetList.json index 3a21dd48c..1c4459b8b 100644 --- a/snippet_data/snippetList.json +++ b/snippet_data/snippetList.json @@ -496,6 +496,23 @@ "hash": "11581e3b40209c7152833aa421c7d18c889b16067c5cc1557b1bb7f604f18982" } }, + { + "id": "useAsync", + "type": "snippetListing", + "title": "useAsync", + "attributes": { + "text": "A hook that handles asynchronous calls.\n\n- Create a custom hook that takes a handler function, `fn`.\n- Define a reducer function and an initial state for the custom hook's state.\n- Use the `React.useReducer()` hook to initialize the `state` variable and the `dispatch` function.\n- Define a `run` function that will run the provided callback, `fn`, while using `dispatch` to update `state` as necessary.\n- Return an object containting the the properties of `state` (`value`, `error` and `loading`) and the `run` function.\n\n", + "tags": [ + "hooks", + "state", + "reducer", + "advanced" + ] + }, + "meta": { + "hash": "e15c637ad5256365c049fdef4529955310e2e71fec1d7d76bf9818a2db789b5c" + } + }, { "id": "useClickInside", "type": "snippetListing", diff --git a/snippet_data/snippets.json b/snippet_data/snippets.json index a82bef027..7d20d46a6 100644 --- a/snippet_data/snippets.json +++ b/snippet_data/snippets.json @@ -796,6 +796,33 @@ "authorCount": 2 } }, + { + "id": "useAsync", + "title": "useAsync", + "type": "snippet", + "attributes": { + "fileName": "useAsync.md", + "text": "A hook that handles asynchronous calls.\n\n- Create a custom hook that takes a handler function, `fn`.\n- Define a reducer function and an initial state for the custom hook's state.\n- Use the `React.useReducer()` hook to initialize the `state` variable and the `dispatch` function.\n- Define a `run` function that will run the provided callback, `fn`, while using `dispatch` to update `state` as necessary.\n- Return an object containting the the properties of `state` (`value`, `error` and `loading`) and the `run` function.\n\n", + "codeBlocks": { + "style": "", + "code": "const useAsync = (fn) => {\n const initialState = { loading: false, error: null, value: null };\n const stateReducer = (_, action) => {\n switch (action.type) {\n case 'start':\n return { loading: true, error: null, value: null};\n case 'finish':\n return { loading: false, error: null, value: action.value};\n case 'error':\n return { loading: false, error: action.error, value: null};\n }\n }\n\n const [state, dispatch] = React.useReducer(stateReducer, initialState);\n\n const run = async (args = null) => {\n try {\n dispatch({ type: 'start' });\n const value = await fn(args);\n dispatch({ type: 'finish', value });\n } catch (error) {\n dispatch({ type: 'error', error });\n }\n };\n \n return { ...state, run };\n};", + "example": "const RandomImage = props => {\n const imgFetch = useAsync(url => fetch(url).then(response => response.json())); \n \n return (\n
\n imgFetch.run('https://dog.ceo/api/breeds/image/random')}\n disabled={ imgFetch.isLoading }\n >\n Load image\n \n
\n { imgFetch.loading &&
Loading...
} \n { imgFetch.error &&
Error { imgFetch.error }
}\n { imgFetch.value && \"avatar\"}\n
\n );\n};\n\nReactDOM.render(, document.getElementById('root'));" + }, + "tags": [ + "hooks", + "state", + "reducer", + "advanced" + ] + }, + "meta": { + "hash": "e15c637ad5256365c049fdef4529955310e2e71fec1d7d76bf9818a2db789b5c", + "firstSeen": "1578594132", + "lastUpdated": "1578594132", + "updateCount": 2, + "authorCount": 2 + } + }, { "id": "useClickInside", "title": "useClickInside", From d3fe1c492a732791e1ca73bef43351d64f7a0e39 Mon Sep 17 00:00:00 2001 From: Schneider Date: Tue, 21 Jan 2020 18:04:55 -0200 Subject: [PATCH 09/12] contributing.md: fix typo --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ffae9dd84..27b8dd1fc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ Here's what you can do to help: - All snippets must contain a title. - All snippets must contain tags, prefixed with `tags:` and separated by commas (optional spaces in-between). - Make sure the first tag in your snippet's tags is one of the main categories, as seen in the `README.md` file or the website. - - Snippet tags must include a difficulty setting (`begginer`, `intermediate` or `advanced`), preferrably at the end of the list. + - Snippet tags must include a difficulty setting (`begginer`, `intermediate` or `advanced`), preferably at the end of the list. - **Snippet titles** should be the same as the name of the component or hook that is present in the snippet. - All snippet titles must be prefixed with `title:` and be at the very first line of your snippet's frontmatter. - Snippet titles must be unique (although if you cannot find a better title, just add some placeholder at the end of the filename and title and we will figure it out). From 424bf15aa6534868605c2eab56f0c427320d6161 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Thu, 30 Jan 2020 21:55:03 +0200 Subject: [PATCH 10/12] Update CONTRIBUTING.md --- CONTRIBUTING.md | 124 +++++++++++++++++++----------------------------- 1 file changed, 49 insertions(+), 75 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 27b8dd1fc..9cb32a23a 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,87 +1,61 @@ # Contribution Guidelines -**30 seconds of React** is a community effort, so feel free to contribute in any way you can. Every contribution helps! +**30 seconds of code** is powered by the community, so feel free to contribute in any way you can to help us! -Here's what you can do to help: +## Tools -- Submit [pull requests](https://github.com/30-seconds/30-seconds-of-react/pulls) with snippets that you have created (see below for guidelines). -- [Open issues](https://github.com/30-seconds/30-seconds-of-react/issues/new) for things you want to see added or modified. -- Be part of the discussion by helping out with [existing issues](https://github.com/30-seconds/30-seconds-of-react/issues). -- Fix typos in existing snippets, improve snippet descriptions and explanations or provide better examples. +Before you begin contributing, you should install the integration-tools globally on your machine: -### Snippet submission and Pull request guidelines +```sh +npm install -g @30-seconds/integration-tools +``` -- **DO NOT MODIFY THE README.md FILE!** Make changes to individual snippet files. **Travis CI** will automatically build the `README.md` file when your pull request is merged. -- **Snippet filenames** must correspond to the title of the snippet. For example, if your snippet is titled `### AwesomeComponent` the filename should be `AwesomeComponent.md`. - - Use `TitleCase`, not `camelCase`, `kebab-case` or `snake_case` when naming components. - - Use `camelCase`, not `TitleCase`, `kebab-case` or `snake_case` when naming custom hooks. - - Avoid capitalization of words, except if the whole word is capitalized (e.g. `URL` should be capitalized in the filename and the snippet title). -- **Snippet metadata** must be included in all snippets in the form of frontmatter. - - All snippets must contain a title. - - All snippets must contain tags, prefixed with `tags:` and separated by commas (optional spaces in-between). - - Make sure the first tag in your snippet's tags is one of the main categories, as seen in the `README.md` file or the website. - - Snippet tags must include a difficulty setting (`begginer`, `intermediate` or `advanced`), preferably at the end of the list. -- **Snippet titles** should be the same as the name of the component or hook that is present in the snippet. - - All snippet titles must be prefixed with `title:` and be at the very first line of your snippet's frontmatter. - - Snippet titles must be unique (although if you cannot find a better title, just add some placeholder at the end of the filename and title and we will figure it out). - - Follow snippet titles with an empty line. -- **Snippet descriptions** must be short and to the point. Try to explain _what_ the snippet does and _how_ the snippet works and what Javascript/React features are used. Remember to include what functions you are using and why. - - Follow snippet descriptions with an empty line. -- **Snippet code** must be enclosed inside ` ```jsx ` and ` ``` `. - - If your snippet is accompanied by CSS code, enclose it inside ` ```css ` and ` ``` ` and present it before the JS/JSX code. - - Remember to start your snippet's code on a new line below the opening backticks. - - Use standard function notation to define your component. For example `function MyComponent(props) { ... }`. - - Do not write components using classes, use [React Hooks](https://reactjs.org/docs/hooks-intro.html) instead. - - Please use Javascript [Semi-Standard Style](https://github.com/Flet/semistandard). - - Try to keep your snippets' code short and to the point. Use modern techniques and features. Make sure to test your code before submitting. - - All snippets must be followed by one (more if necessary) test case after the code, in a new block enclosed inside ` ```jsx ` and ` ``` `. The syntax for this is `ReactDOM.render(, document.getElementById("root"));`. Use multiline examples only if necessary. - - Try to make your component name unique, so that it does not conflict with existing snippets. -- Snippets should be as brief as possible, without sacrificing functionality. If your snippet seems longer than most, you can still submit it, and we can help you shorten it or figure out ways to improve it. -- Snippets _should_ solve real-world problems, no matter how simple. -- Snippets _should_ be abstract enough to be applied to different scenarios. -- You can start creating a new snippet, by using the [snippet template](snippet-template.md) to format your snippets. +This will allow you to use our customized tools for all of our content repositories. -### Additional guidelines and conventions regarding snippets +## How you can help -- When describing snippets, refer to methods, using their full name. For example, use `Array.prototype.reduce()`, instead of `reduce()`. -- When using React Hooks, refer to the specific hooks with their full names, such as `React.useState()` and `React.useEffect()`. -- When using `React.useState()`, try matching the name of the state variable to the function that sets it. For example, use `[isShown, setIsShown]` instead of `[isShown, setShown]`. -- When using `React.useEffect()`, only return a function if you have to clean up. In that case, name that function `cleanup()`. -- Destructure your component's `props` whenever possible. If any of your props take default parameters, specify their default values in the destructured object. -- If your snippet uses recursion, explain the base cases. -- Always use `function MyComponent(props)` or `function MyComponent({ ... })` for function definitions. -- Use variables only when necessary. Prefer `const` when the values are not altered after assignment, otherwise, use `let`. Avoid using `var`. -- Use `camelCase` for function and variable names, if they consist of more than one word. -- Use `TitleCase` for component names. -- Try to give meaningful names to variables. For example use `letter`, instead of `lt`. Some exceptions to convention are: - - `arr` for arrays (usually as the snippet function's argument). - - `str` for strings. - - `num` or `n` for a numeric value (usually as the snippet function's argument). - - `el` for DOM elements (usually as the snippet function's argument). - - `val` or `v` for value (usually when iterating a list, mapping, sorting etc.). - - `acc` for accumulators in `Array.prototype.reduce()`. - - `(a,b)` for the two values compared when using `Array.prototype.sort()`. - - `i` for indexes. - - `fn` for function arguments. - - `nums` for arrays of numbers. -- Use `()` if your function takes no arguments. -- Use `_` if an argument inside some function (e.g. `Array.prototype.reduce()`) is not used anywhere in your code. -- Specify default parameters for arguments, if necessary. It is preferred to put default parameters last unless you have a pretty good reason not to. -- If your snippet's function takes variadic arguments, use `...args` or `...rest` (although in certain cases, it might be needed to use a different name). +- Submit pull requests with new snippets (see guidelines below) or snippet updates (tags, descriptions, explanations, typos, examples, code improvements). +- Open issues for things you want to see added, modified, discuss ideas or help out with existing issues. + +## Ground rules + +Breaking any of these rules will result in your pull request being closed. Please follow these guidelines above all else: + +- **Always be polite and respectful to others** and try to follow the advice of the moderators/collaborators/owners. +- **Only modify snippet files**, never modify the generated files in the `snippet_data` directory. +- **Use the integration tools commands** to generate new snippets, ensuring they have the correct name and are in the correct location. +- **Follow snippet format exactly**, otherwise your snippets will not be recognized correctly by the tools responsible for publishing them on the website. This includes such things as spacing and empty lines - if you accidentally make a mistake, consult the repository's [snippet template](snippet-template.md). +- **Snippets should solve real-world problems**, no matter how simple and should be abstract enough to be applied to different scenarios. + +## Snippet creation + +After installing the integration tools, you can run the following command: + +```sh +create-new-snippet +``` + +Replace `` with the name of the snippet you are adding. + +## Snippet guidelines + +- Snippets must have all their frontmatter sections (title, tags etc.) filled. +- Snippet titles must correspond to the filename and follow the language and repository's naming conventions. +- Snippet tags must be comma-separated, contain a primary tag as seen on the website as their first tag and an expertise tag (`beginner`, `intermediate` or `advanced`) as their last tag. +- Snippet descriptions must be short and to the point. Explain *what* the snippet does and detail *how* the snippet works and the language features used in it. +- Snippet code and examples must be enclosed in appropriate, language-tagged blocks as shown in the snippet template, be short and use modern techniques and features. Also make sure to test your code before submitting. +- If your snippet contains arguments with default parameters, explain what happens if they are omitted when calling the function and what the default case is. Specify default parameters for arguments only if necessary. +- If your snippet uses recursion, use the `recursion` tag and explain the base cases. +- Try to strike a balance between readability, brevity, and performance. - Always use soft tabs (2 spaces), never hard tabs. -- Omit curly braces (`{` and `}`) whenever possible. +- Leave a single space after a comma (`,`) character (both in the description and code). +- Define multiple variables on the same line, if possible. Use meaningful names (e.g. `letter` instead of `lt`) and follow existing conventions as seen in other snippets. Do not use trailing or leading underscores in variable names. +- When describing snippets, refer to methods, using their full name. For example, use `Array.prototype.reduce()`, instead of `reduce()`. When using React Hooks, refer to the specific hooks with their full names, such as `React.useState()` and `React.useEffect()`. +- When using `React.useState()`, try matching the name of the state variable to the function that sets it. For example, use `[isShown, setIsShown]` instead of `[isShown, setShown]`. When using `React.useEffect()`, only return a function if you have to clean up. In that case, name that function `cleanup()`. +- Destructure your component's `props` whenever possible. If any of your props take default parameters, specify their default values in the destructured object. +- Always use `function MyComponent(props)` or `function MyComponent({ ... })` for function definitions. - Always use single quotes for string literals. Use template literals, instead, if necessary. - When rendering JSX, use double quotes, instead of single quotes. -- Prefer using `Array` methods whenever possible. -- Prefer `Array.prototype.concat()` instead of `Array.prototype.push()` when working with `Array.prototype.reduce()`. -- Use strict equality checking (`===` and `!==` instead of `==` and `!=`), unless you specifically have reason not to. -- Prefer using the ternary operator (`condition ? trueResult : falseResult`) instead of `if else` statements whenever possible. -- Avoid nesting ternary operators (but you can do it if you feel like you should). -- You should define multiple variables (e.g. `const x = 0, y = 0`) on the same line whenever possible. -- Do not use trailing or leading underscores in variable names. -- Use dot notation (`object.property`) for object properties, when possible. Use bracket notation (`object[variable]`) when accessing object properties using a variable. -- Use arrow functions as much as possible, except when you can't. -- Use semicolons whenever necessary. -- Leave a single space after a comma (`,`) character. -- Try to strike a balance between readability, brevity, and performance. +- Use strict equality checking (`===` and `!==` instead of `==` and `!=`). +- Prefer using the ternary operator (`condition ? trueResult : falseResult`) instead of `if else` statements whenever possible. Avoid nesting ternary operators. - Never use `eval()`. Your snippet will be disqualified immediately. From d901535906dfddc33ca188311fa0c88e4528aba4 Mon Sep 17 00:00:00 2001 From: Angelos Chalaris Date: Tue, 3 Mar 2020 21:54:20 +0200 Subject: [PATCH 11/12] Update Carousel.md Resolves #90 --- snippets/Carousel.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/snippets/Carousel.md b/snippets/Carousel.md index f1859eb43..4b220b614 100644 --- a/snippets/Carousel.md +++ b/snippets/Carousel.md @@ -5,7 +5,7 @@ tags: visual,children,state,effect,intermediate Renders a carousel component. -- Use the `React.setState()` hook to create the `active` state variable and give it a value of `0` (index of the first item). +- Use the `React.useState()` hook to create the `active` state variable and give it a value of `0` (index of the first item). - Use an object, `style`, to hold the styles for the individual components. - Use the `React.useEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`. - Destructure `props`, compute if visibility style should be set to `visible` or not for each carousel item while mapping over and applying the combined style to the carousel item component accordingly. From aa3f7c094ce53c7dff72f176e9829abbd982c9eb Mon Sep 17 00:00:00 2001 From: 30secondsofcode <30secondsofcode@gmail.com> Date: Tue, 3 Mar 2020 19:55:21 +0000 Subject: [PATCH 12/12] Travis build: 282 --- snippet_data/snippetList.json | 4 ++-- snippet_data/snippets.json | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/snippet_data/snippetList.json b/snippet_data/snippetList.json index 1c4459b8b..c2d043ad1 100644 --- a/snippet_data/snippetList.json +++ b/snippet_data/snippetList.json @@ -57,7 +57,7 @@ "type": "snippetListing", "title": "Carousel", "attributes": { - "text": "Renders a carousel component.\n\n- Use the `React.setState()` hook to create the `active` state variable and give it a value of `0` (index of the first item).\n- Use an object, `style`, to hold the styles for the individual components.\n- Use the `React.useEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`.\n- Destructure `props`, compute if visibility style should be set to `visible` or not for each carousel item while mapping over and applying the combined style to the carousel item component accordingly.\n- Render the carousel items using `React.cloneElement()` and pass down rest `props` along with the computed styles.\n\n", + "text": "Renders a carousel component.\n\n- Use the `React.useState()` hook to create the `active` state variable and give it a value of `0` (index of the first item).\n- Use an object, `style`, to hold the styles for the individual components.\n- Use the `React.useEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`.\n- Destructure `props`, compute if visibility style should be set to `visible` or not for each carousel item while mapping over and applying the combined style to the carousel item component accordingly.\n- Render the carousel items using `React.cloneElement()` and pass down rest `props` along with the computed styles.\n\n", "tags": [ "visual", "children", @@ -67,7 +67,7 @@ ] }, "meta": { - "hash": "4e224ce57a85a9061c065603496ae2a80db43d2ab7908d1c08c7dcbe5779a2d6" + "hash": "18bc23f64d46aa17912ec9f854cde7ebff2395ef3936da2e7e60870221e9f47b" } }, { diff --git a/snippet_data/snippets.json b/snippet_data/snippets.json index 7d20d46a6..44be288f5 100644 --- a/snippet_data/snippets.json +++ b/snippet_data/snippets.json @@ -88,7 +88,7 @@ "type": "snippet", "attributes": { "fileName": "Carousel.md", - "text": "Renders a carousel component.\n\n- Use the `React.setState()` hook to create the `active` state variable and give it a value of `0` (index of the first item).\n- Use an object, `style`, to hold the styles for the individual components.\n- Use the `React.useEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`.\n- Destructure `props`, compute if visibility style should be set to `visible` or not for each carousel item while mapping over and applying the combined style to the carousel item component accordingly.\n- Render the carousel items using `React.cloneElement()` and pass down rest `props` along with the computed styles.\n\n", + "text": "Renders a carousel component.\n\n- Use the `React.useState()` hook to create the `active` state variable and give it a value of `0` (index of the first item).\n- Use an object, `style`, to hold the styles for the individual components.\n- Use the `React.useEffect()` hook to update the value of `active` to the index of the next item, using `setTimeout`.\n- Destructure `props`, compute if visibility style should be set to `visible` or not for each carousel item while mapping over and applying the combined style to the carousel item component accordingly.\n- Render the carousel items using `React.cloneElement()` and pass down rest `props` along with the computed styles.\n\n", "codeBlocks": { "style": "", "code": "function Carousel(props) {\n const [active, setActive] = React.useState(0);\n let scrollInterval = null;\n const style = {\n carousel: {\n position: 'relative'\n },\n carouselItem: {\n position: 'absolute',\n visibility: 'hidden'\n },\n visible: {\n visibility: 'visible'\n }\n };\n React.useEffect(() => {\n scrollInterval = setTimeout(() => {\n const { carouselItems } = props;\n setActive((active + 1) % carouselItems.length);\n }, 2000);\n return () => clearTimeout(scrollInterval);\n });\n const { carouselItems, ...rest } = props;\n return (\n
\n {carouselItems.map((item, index) => {\n const activeStyle = active === index ? style.visible : {};\n return React.cloneElement(item, {\n ...rest,\n style: {\n ...style.carouselItem,\n ...activeStyle\n }\n });\n })}\n
\n );\n}", @@ -103,10 +103,10 @@ ] }, "meta": { - "hash": "4e224ce57a85a9061c065603496ae2a80db43d2ab7908d1c08c7dcbe5779a2d6", + "hash": "18bc23f64d46aa17912ec9f854cde7ebff2395ef3936da2e7e60870221e9f47b", "firstSeen": "1542137095", - "lastUpdated": "1568839108", - "updateCount": 12, + "lastUpdated": "1583265260", + "updateCount": 13, "authorCount": 3 } },