npx create-react-app myapp
cd myapp
npm start
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import Films from './Films';
ReactDOM.render(
<Films />,
document.getElementById('root')
);
Films.js
// ...
import Title from './Title.js';
import Search from './Search.js';
import List from './List.js';
export default function Films() {
return (
<div className="Films">
<Title />
<Search />
<List />
</div>
);
}
Films.js
// ...
import Title from './Title.js';
import Search from './Search.js';
import List from './List.js';
export default function Films() {
return (
<div className="Films">
<Title />
<Search />
<List />
</div>
);
}
Search.js
import React from 'react';
import './Search.css';
export default function Search() {
return (
<span className="Search">
Search: <input value="foo" />
</span>
);
}
Search.css
.Search {
margin: 0.4vh 2.7vw;
display: flex;
flex-direction: row;
align-items: center;
}
.Search input {
margin-left: 0.4em;
font-size: 1em;
flex-grow: 1;
}
Films.js
// ...
import Title from './Title.js';
import Search from './Search.js';
import List from './List.js';
export default function Films() {
return (
<div className="Films">
<Title />
<Search />
<List />
</div>
);
}
List.js
export default function List() {
const films = [ {"name": "The Matrix", ...} ];
return (
<div className="List"><table>
<thead><tr><th>Film</th><th>Genre...
<tbody> ... </tbody>
</table></div>
);
}
List.js
<tbody>{
films.map(f =>
<tr>
<td>{f.name}</td>
<td>{f.genre}</td>
<td>{f.loveorhate}</td>
<td>{f.reasoning}</td>
</tr>
)
}</tbody>
Films.js
export default function Films() {
return (
<div className="Films">
<Title />
<Search />
<List highlight="odfath"/>
</div>
);
}
List.js
export default function List(props) {
...
}
List.js
films.map(f =>
<tr>
<td>{highlight(props.highlight, f.name)}</td>
<td>{f.genre}</td>
<td>{f.loveorhate}</td>
<td>{f.reasoning}</td>
</tr>
)
Web 1.0:
Web 1.0:
Web 2.0:
Web 2.0:
import React, { useState } from 'react';
export default function Search() {
const [ search, setSearch ] = useState("");
const searchChanged = (e) => {
setSearch(e.target.value);
console.log(`Pretending to search: ${e.target.value}`);
};
return (
<span className="Search">
Search:
<input
value={search}
onChange={searchChanged}
/>
</span>
);
}
...
const calcClass = () => {
if (search.length > 3) {
return "bad";
} else {
return "";
}
}
...
<input
value={search}
onChange={searchChanged}
className={calcClass()}
/>
...
...
const searchChanged = (e) => {
setSearch(e.target.value);
console.log(`Pretending to search: ${e.target.value}`);
};
return (
...
<input
value={search}
onChange={searchChanged}
/>
...
export default function Search(props) {
const [ search, setSearch ] = useState("");
return (
<span className="Search">
Search:
<input
value={search}
onChange={props.searchChanged}
/>
</span>
);
}
export default function Search(props) {
const [ search, setSearch ] = useState("");
return (
<span className="Search">
Search:
<input
value={props.search}
onChange={props.searchChanged}
/>
</span>
);
}
export default function Films() {
const [ search, setSearch ] = useState("");
const searchChanged = (e) => {
setSearch(e.target.value);
console.log(`Pretending to search: ${e.target.value}`);
};
return (
<div className="Films">
<Title />
<Search
search={search}
searchChanged={searchChanged}
/>
<List highlight={search}/>
</div>
);
}
When you understand that cycle, you will understand the rules e.g.:
The (create-react-app) build: