React
Documentation (easy read... highly recommended after you've finished the workshop): https://facebook.github.io/react/docs/hello-world.html
Workshop start
Recommended VS Code extensions
- npm intellisense, path autocomplete, path intellisense, typescript react code snippets
git clone https://github.com/pkovacevic/kulendayz-react-workshop
## Install npm dependencies, React etc.
npm install
## Windows
setx ASPNETCORE_ENVIRONMENT "Development"
## Mac Linux
export ASPNETCORE_ENVIRONMENT=development
## Run the web server
dotnet run
Index.cshtml
<div id="root"></div>
<script src="~/dist/main.js"></script>
main.js
import * as React from 'react';
import * as ReactDOM from 'react-dom';
ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('root')
);
Hello World
React component
Defining and exporting component
App.tsx
import * as React from 'react';
class App extends React.Component {
render() {
return (
<div>
Hello World
</div>
);
}
}
export default App;
Importing components
Use relative paths to import your own components. Omit the extension!
import App from './App';
...
...
<App />
React developer toolbox
Jsx
Expands JavaScript and allows us to store dom elements inside variables.
const header = <h1>Hello World</h1>;
Limitation: only a single root element allowed in the expression.
// not allowed
const x = (
<div>1</div>
<div>2</div>
);
// allowed!
const y = (
<div>
<div>1</div>
<div>2</div>
</div>
);
Injecting JavaScript
Use curly braces. Inside braces JavaScript gets executed.
class App extends React.Component {
render() {
return (
<div>
Hello World {new Date().getFullYear()}
</div>
);
}
}
Hello World 2017
Any JavaScript will do.
const someFunction = () =>{
return "Hello";
}
class App extends React.Component {
render() {
return (
<div>
{someFunction() + "... JavaScript :)"}
</div>
);
}
}
Hello... Javascript :)
Conditional rendering ("if")
class App extends React.Component {
render() {
const showFooter = false;
return (
<div>
{/* Show footer only when showFooter => true. */} }
{showFooter &&
<div>Kulendayz2017</div>
}
</div>
);
}
}
List rendering ("for loop")
React renders lists by concatenating list items.
class App extends React.Component {
render() {
const lecturers = ['Toni', 'Dobrisa', 'Ivan', 'Pero'];
return (
<div>
{lecturers}
</div>
);
}
}
ToniDobrisaIvanPero
If our list contains components, we can expect a better output.
class App extends React.Component {
render() {
const lecturers = ['Toni', 'Dobrisa', 'Ivan', 'Pero'];
const lecturerDivList = lecturers.map((name) =>
<div>{name}</div>
);
return (
<div>
{lecturerDivList}
</div>
);
}
}
Toni
Dobrisa
Ivan
Pero
It's more practical to go inline.
class App extends React.Component {
render() {
const lecturers = ['Toni', 'Dobrisa', 'Ivan', 'Pero'];
return (
<div>
{lecturers.map((name) =>
<div>{name}</div>
)}
</div>
);
}
}
To help React optimally follow the changes on the list, like when adding, removing, updating elements - you have to provide row identifier (key attribute).
class App extends React.Component {
render() {
const lecturers = ['Toni', 'Dobrisa', 'Ivan', 'Pero'];
return (
<div>
{lecturers.map((name, index) =>
{/* Not the smartest row identifier :) */} }
<div key={index}>{name}</div>
)}
</div>
);
}
}
Handling events
Like DOM events, just camel case instead of lower case.
const clickEvent = () => {
alert('boom');
}
class App extends React.Component {
render() {
return (
<div>
<div onClick={clickEvent}>Clickable div</div>
</div>
);
}
}
Other
className instead of class. Class keyword is reserved in js.
class App extends React.Component {
render() {
return (
<div>
<button className="btn btn-info">Click</button>
</div>
);
}
}
htmlFor instead of for. For keyword is reserved in js.
class App extends React.Component {
render() {
return (
<div>
<label htmlFor=""></label>
</div>
);
}
}