diff --git a/10-react/react-thinking/components.md b/10-react/react-thinking/components.md new file mode 100644 index 0000000..533789d --- /dev/null +++ b/10-react/react-thinking/components.md @@ -0,0 +1,78 @@ +# Components + +## Abstraction + +To recap, components are one of the key features of React as they facilitate composition, maintenance and reusability of isolated pieces of UI: + +* Components can be pieced together in various permutations +* Changes can be made to a particular component easily, without having to make consequent changes to other components +* Components can be used repeatedly in various other components of an app + +Different parts of an app's view can thus be abstracted with great flexibility, nested within one another as components. + +![alt tag](https://cdn.css-tricks.com/wp-content/uploads/2016/03/brad-westfall-2.svg) + +[Source](https://cdn.css-tricks.com/wp-content/uploads/2016/03/brad-westfall-2.svg) + +## Naming components + +Because components can be reused repeatedly anywhere in an app, one convention is to name a component's props from that component's perspective, rather than that of its parent. This makes sense as the component's parent may vary,, depending on the context in which it is used within the app. + +Consider the example of an Avatar component within a Post component of an app: + +~~~~ +function Post(props) { + return ( +
+
+ {props.author.name} +
+ +
+ {props.text} +
+
+ ); +} +~~~~ +While the Avatar component will be used with the Post component's 'author' prop as an input, the Avatar component's props should be named as those of a 'user' rather than an 'author': + +~~~~ +function Avatar(props) { + return ( + {props.user.name} + ); +} +~~~~ +This follows from the fact that the Avatar component could be used elsewhere in the app, within a component with props other than an 'author' prop. + +[Further reading](https://facebook.github.io/react/docs/components-and-props.html#extracting-components) + +## What should be a component? + +Literally every piece of UI could be defined as a component, to the greatest level of granularity: + +![alt tag](https://facebook.github.io/react/img/blog/thinking-in-react-components.png) + +[Source](https://facebook.github.io/react/docs/thinking-in-react.html#step-1-break-the-ui-into-a-component-hierarchy) + +But this might not be necessary for the purposes of the app you are building. 2 helpful guidelines for what parts of the UI should be defined as components are: + +* Any part of the UI that will be reused repeatedly, e.g. buttons, panels, avatars, etc + +* Any part of the UI that is complex, e.g. the app, a feed story, comments, extracting-components + +## Components as pure functions + +All React components must act like pure functions with respect to their props, i.e.: + +* Components must not change their inputs + +* Components must always return the same result for the same inputs + +But application UIs are increasingly dynamic and change over time. These requirements are instead met with state. + +[Further reading](https://facebook.github.io/react/docs/components-and-props.html#props-are-read-only) diff --git a/10-react/react-thinking/debugging.md b/10-react/react-thinking/debugging.md new file mode 100644 index 0000000..a391444 --- /dev/null +++ b/10-react/react-thinking/debugging.md @@ -0,0 +1,9 @@ +# Top-down data flow and debugging + +Some helpful points on debugging follow from the cascading nature of data in React: + +* If the props and state are correct, all you need to check is render() or the functions it calls + +* If the state is wrong, check the setState() calls + +* If the props are wrong, check the parent components that passed those props down diff --git a/10-react/react-thinking/readme.md b/10-react/react-thinking/readme.md new file mode 100644 index 0000000..1f0c775 --- /dev/null +++ b/10-react/react-thinking/readme.md @@ -0,0 +1,6 @@ +#React thinking + +##Objectives + +* Review key features of components, state and use of components and state +* Consider implications on app set-up and debugging diff --git a/10-react/react-thinking/state.md b/10-react/react-thinking/state.md new file mode 100644 index 0000000..2796400 --- /dev/null +++ b/10-react/react-thinking/state.md @@ -0,0 +1,31 @@ +# State + +## Implications of top-down data flow + +State is private, local, encapsulated within and controlled only by that component. A component's state can be passed down as props to its child components, but the children cannot update that component's state directly. + +If a component is set up such that its state can be modified depending on its children's input, this can be done by way of a function passed down as a prop. If its state can be modified depending on its grandchildren's input, that function needs to be passed down another level as a prop. + +This pattern can get pretty complicated depending on the complexity of the app and the extent of interdependence between components. For this reason, React could instead be used in conjunction with tools to manage state, such as [Redux](http://redux.js.org/). + +## Where should state reside? + +You may find that several components of your app need to reflect the same changing data. The shared state thus needs to be lifted up to a common ancestor. This should probably be their closest common ancestor, bearing in mind in particular that every additional level by which the state is lifted means another level it must be passed down as a prop. + +In other words: + +* Identify every component that renders something based on the state. + +* Find the lowest common ancestor component. + +* The state should ideally reside at that component, but can also reside in a component higher up in the hierarchy + +## Of a component's data, which should be state? + +DRY means that the set of mutable state required by your app should be kept to the minimum. Some guidelines to figure out which data is state are: + +* If the data is passed from a parent as props, it probably is not state. State can only be modified within a component and not by its children. + +* If the data remains unchanged over time, it probably is not state. Remember that state can be modified and determine how child components are rendered. + +* If the data can be computed based on any other state or props within the component, it probably is not state. If you are building a todo list with an array of todo items, and want to render the todo count, it is probably unnecessary to keep a separate state variable for the count. This variable would be redundant as the array's length can be easily computed.