A component can contain a single element or many elements, and even many components. Component-driven design is a new paradigm shift of how we think about user interfaces, and helps us deliver complex user interfaces much more simply.
Note that you must use a compiler, such as Babel, to convert newer features, such as classes, into code that is readable by a web browser. You will also need to use a build tool such as Webpack to automatically compile code and carry out other build tasks.
Zero configuration tools, such as createReactApp, can be easily utilized, that set all these tools up for you. Let's create a new component named sawSelector. First, we'll import react and component from the React library.
Then let's create our class called sawSelector, which extends from the component class. Inside the class, we will add a method named render, which is what is executed when the component loads, and contains the desired output for our component.
Let's add a button which will update our application state. We will trigger on one of the many event handlers available to us, in this case onClick, which will be triggered when the button is clicked. We will define the function, which will be fired on click, and name it handleClick.
Within this callback is where we update the application state. Assigning a value with React's special setState function will modify the state, and automatically rerender the function containing the updated state.
React will derive e.target.value from the value attribute of the element, and we will also need to define a unique key, so React knows which element is triggering the update. We could also add some styling to our button.
React carries out its own diffing process, changing only the DOM elements that need to be updated, which is efficient, and greatly increases rendering performance. There are many helper functions available in React called life cycle methods.
Each life cycle method is triggered at some point within React's render timeline, and you can use them when you need your code fired at a specific time. For example, componentDidUpdate is triggered every time the component state is updated.
Usage of these life cycle methods are completely dependent upon your individual use case and needs. You can find a list of all life cycle methods by reading through React's documentation. React utilizes a unidirectional data flow model, meaning data flows from the most-parent component down to the most-child component.
If there are many components that need access to a piece of state, the state should be stored at a component, which is a common ancestor to all of the child components needing access to that piece of state, but on the level that is deepest down the rendering tree.
This avoids components from unnecessarily rerendering on state changes if they do not need access to that piece of state. Data is passed from parent components to child components via props. Props are used instead of state when the data does not need to be modified by the component using it.
They also should be used whenever possible instead of state to avoid unnecessary code complexity, and improve rendering performance. If a child component needs to modify state from a parent component, functions can also be passed as props from the parent component down to child components.
Passing props down many levels can be a bit verbose, but helps keep the data model simple, and easy to debug. When you start dealing with many, many layers of parent-child components, or start having a hard time tracking down function props through numerous layers of components, it may be a good idea to look into external state management libraries.
There are a variety of libraries which will help in the setting and retrieval of pieces of state. However, you'll find that most apps can manage state locally in React. Local state is the simplest way to manage your application state, and avoids the unnecessary complexities of external state management tools.
Smart planning around your component-driven design from the start of a project goes a long way in reducing inherent complexities introduced from a growing code base.