230513-1342.wiki
1 %title An Brief Introduction to React 2 :dev:javascript:web:react: 3 %date 2023-05-13 13:42 4 %update 2023-05-17 01:43 5 6 React uses `Components` to do basically everything. Technically (Generally?) Components are Javascript functions[#]_ that return HTML elements. Where it all comes together (if you're using `create-react-app`) is the `index.js` file which contains this line: 7 8 {{{javascript 9 ReactDOM.createRoot(document.getElementById('root')).render(<App />) 10 }}} 11 12 Which renders the React Component defined by `App` into the `root` element of `index.html`. 13 14 Though it doesn't really matter what's in the `App` function, it will matter to us later, so it currently looks like this: 15 16 {{{javascript 17 const App = () => { 18 console.log('Hello from component') 19 return ( 20 <div> 21 <p>Hello world</p> 22 </div> 23 ) 24 } 25 }}} 26 27 See, it's a function that takes no arguments, using the ECMA6 Arrow definition of a function. It runs javascript, so you can interact with the console, and it returns something approximating HTML. 28 29 = A detour into JSX = 30 JSX is a syntax extension to Javascript that allows writing HTML-like markup inside a JS file. Although it looks like HTML, it isn't really, it gets compiled down to Javascript by a compiler (`Babel` in the case of `create-react-app`). JSX is quite similar to HTML, but it allows dynamic execution in HTML elements using the `{ curly brace }` syntax. Think of it like a templating language, which has a tree like structure similar to HTML. One difference is that *every* tag must be closed. 31 32 For comparison: 33 34 {{{html 35 <br> 36 }}} 37 38 {{{jsx 39 <br /> 40 }}} 41 42 = Props to React = 43 Components can be nested. Components can take data. Components can run functions. It's all components all the way down! You're using Javascript after-all, why wouldn't these things be possible? 44 You can nest components by simply calling the function as a closed JSX tag in the HTML you're returning. But passing data is done by so called "props". Really they're just a parameter that your function takes that contains the data you can manipulate inside the HTML markup, again through the magic of JSX. 45 46 Because Javascript is Javascript, convention dictates that you have a single parameter entitled `props` which takes an object that defines all the data you want to pass to the function. Let's take a look at the example from up top but with all the additional things we've just learned. 47 48 {{{javascript 49 const Hello = (props) => { 50 console.log(props) 51 return ( 52 <div> 53 <p> 54 Hello {props.name}, you are {props.age} years old 55 </p> 56 </div> 57 ) 58 } 59 60 const App = () => { 61 const name = 'Peter' 62 const age = 10 63 return ( 64 <div> 65 <h1>Greetings</h1> 66 <Hello name='Maya' age={26 + 10} /> 67 <Hello name={name} age={age} /> 68 </div> 69 ) 70 } 71 }}} 72 73 Here we've defined 2 React Components, `Hello` and `App`. App nests the Hello component inside it, and passes each a different value for their props. We can both "hard code" values to pass to props, or it can be the output of some javascript execution, but in that case we must wrap it in `{ curly braces }`. Despite props being a single object being passed, we can add any number of arbitrary fields to it. These fields can then be accessed using javascript and dot notation to extract the exact value from the object to be rendered. 74 Note: We cannot render an Object! We have to render base types like strings or integers. Objects are not valid as a React child!! 75 76 React also allows us a special kind of state, that we update in a functional style. Presumably, there are many ways to manage this state, including [redux](https://github.com/reduxjs/redux) is what manages the local state when it gets out of hand. (Let's pass around a giant immutable map like in Clojure!~) 77 78 State is defined through the help of a React library, `useState`. It works like so: 79 80 {{{javascript 81 import { useState } from 'react' 82 83 const App = () => { 84 const [state, setState] = { name: "Voidrynth", age: 36 } 85 return ( 86 <div> 87 <h1>Greetings</h1> 88 <Hello name={state.name} age={state.age} /> 89 </div> 90 ) 91 } 92 }}} 93 94 = Functions and Event Handlers = 95 React Hooks are the style of React that's recommended, and in it, everything is a function. Our state must also be immutable for React to work well(?). This means a Functional Programming style! Exciting :3 96 97 To override event handlers we use callbacks, callbacks must be functions. We can override a button like so: 98 99 {{{javascript 100 const App = (props) => { 101 const onClick = () => { 102 alert("Hello!") 103 } 104 105 return ( 106 <> 107 <button onClick={onClick}> Knock Knock </button> 108 </> 109 ) 110 } 111 }}} 112 113 This button has our onClick definition (which is a function!) that gets called on the button's `onClick`. This is an event handler, but in this case we don't care about the event, because we assume it can only mean one thing. 114 Notably when we do this, all the element's functionality gets overridden! If your element does something by default, or as a side effect of interaction, you got to manage that too! 115 116 This is particularly important with text boxes: 117 118 {{{javascript 119 import { useState } from 'react' 120 121 const App = (props) => { 122 const [text, setText] = useState('Type me...') 123 124 return ( 125 <> 126 <input value={text} /> 127 </> 128 ) 129 } 130 }}} 131 132 Now your user won't be able to change the text in this input box, because none of their input functionality remains. Fixing this requires adding back that functionality with our controlled state 133 134 {{{javascript 135 import { useState } from 'react' 136 137 const App = (props) => { 138 const [text, setText] = useState('Type me...') 139 140 const onChange = (event) => { 141 setState(event.target.value) 142 } 143 144 return ( 145 <> 146 <input value={text} onChange={onChange}/> 147 </> 148 ) 149 } 150 }}} 151 152 Now your state will be updated whenever the user types. This is an event callback which also passes the event that caused it. 153 154 Finally, despite React over-writing all actions, it cannot stop default actions. So we have to manually intercept those. 155 156 {{{javascript 157 const App = (props) => { 158 const onClick = (event) => { 159 event.preventDefault() 160 alert("Hello!") 161 } 162 163 return ( 164 <> 165 <form> 166 <button type="submit" onClick={onClick}> Knock Knock </button> 167 </form> 168 </> 169 ) 170 } 171 }}} 172 173 Normally a form submit would refresh the page and stuff, but we don't want that. 174 175 .. [#] Technically JSX, but we'll get into that in a bit 176 177 ----- 178 = Backlinks = 179 180 - [[230330-0108|Learning Front-End Development]]