#Frontend

Kickstarta din Front-end med React - Del 3: Komponenter och props

 

Detta är del 3 i bloggen Kickstarta din Front-end med React. I del 1 går vi igenom installation av Node.js, Create React App och Yarn. Vi går också igenom hur du startar appen. Om du inte känner dig bekväm med att intallera detta själv så kan du läsa del 1 här: Kickstarta din Front-end med React - Del 1: Förberedelser.

I del 2 av bloggen går vi igenom JSX och React. Hur Babel översätter JSX till anrop av React.createElement och fokuserar på dess parametrar: component, props, och ...children. Du kan läsa del 2 här: Kickstarta din Front-end med React - Del 2: React och JSX.

 

Jag utgår från att du skapat ett projekt med Create React App och öppnat projektet i din texteditor.

Följande versioner av programvara används:

node@6.11.0
npm@3.10.10
yarn@0.24.6
create-react-app@1.3.1

 

src/App.js

Öppna App.js precis som i del 2 av bloggen, där finner du följande:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
  render() {
    return (
      <div className="App">
        <div className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <h2>Welcome to React</h2>
        </div>
        <p className="App-intro">
          To get started, edit <code>src/App.js</code> and save to reload.
        </p>
      </div>
    );
  }
}

export default App;

Vi ska nu börja redigera lite kod och skapa våra egna komponenter. Komponenten ovan har i detta fall två children: <div className="App-header"> och <p className="App-intro">. Tänk dig att vi skriver en större app, då är det fördelaktigt att kunna återanvända kod på ett lätt sätt. Det är precis detta React möjliggör. Vi kommer att skapa en AppHeader-komponent och en AppIntro-komponent.

 

AppHeader

Vi kommer att bryta ut hela AppHeader div-elementet och skapa en egen komponent. För att göra detta skapar vi helt enkelt en ny funktion vid namn AppHeader:

function AppHeader () {
return (
<div className="App-header"> <img src={logo} className="App-logo" alt="logo" /> <h2>Welcome to React</h2>
</div>
)
}

 

AppIntro

Vi gör precis samma sak med AppIntro:

function AppIntro () {
return (
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
)
}

 

Nu har vi två funktioner som gör exakt samma sak som det två elementen i vår app, nu måste vi bara anropa dom. För att anropa dom gör vi följande:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
render() {
return (
<div className="App">
<AppHeader />
<AppIntro />
</div>
);
}
}

function AppHeader () {
return (
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>
)
}

function AppIntro () {
return (
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
)
}

export default App;

Tack vare JSX kan vi anropa våra funktioner som om de vore HTML! Spara filen och ta upp webbsidan i din webbläsare och hemsidan bör se likadan ut som tidigare. 

Vi kan också skriva om dessa funktionsanrop kortare, med hjälp av ES6. Jag kommer i fortsättningen av blogginläggen skriva dom på detta sätt:

function AppIntro () {
return (
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>
)
}

Blir följande:

const AppIntro = () =>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>

Notera avsaknaden av return. ES6 pilfunktion returnerar implicit. Jag kommer inte djupdyka i ES6 (eller ES2015 som det heter officiellt) men du kan läsa mer om det här: https://babeljs.io/learn-es2015/

Vi uppdaterar vår kod med denna syntax:

import React, { Component } from 'react';
import logo from './logo.svg';
import './App.css';

class App extends Component {
render() {
return (
<div className="App">
<AppIntro />
<AppHeader />
</div>
);
}
}

const AppHeader = () =>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to React</h2>
</div>

const AppIntro = () =>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>

export default App;

Vi har nu delat upp funktionalitet som vi kan tänkas återanvända på webbsida genom att skapa två helt egna separata komponenter. Detta är ett återkommande koncept när man utvecklar i React. Att försöka bryta ut de minsta komponenterna och återanvända dom för att bygga större komponenter. 

 

props

Att skapa statiska komponenter kan vara nyttigt, men att skapa komponenter som tar emot data är det som gör React kraftfullt! Om en komponent bryts ned till en mindre beståndsdel, och dessutom kan ta emot data så kan vi återanvända den på många olika ställen med olika syften.

En React-komponent i dess simplaste form är en funktion som vi applicerar, utan något argument. precis som de två funktionerna ovan vi definierat. Om vi vill att vår komponent ska bero på data vi skickar till den så lägger vi till ett argument till funktionen: props:

const AppHeader = (props) =>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to {props.welcome}</h2>
</div>;

Nu är vår komponen redo att ta emot en prop  vid namn welcome. Notera måsvingarna som omsluter props.welcome, det är ett sätt för oss att evaluera kod innuti komponenten. Vi kan alltså använda oss av utryck i vår komponent. Om vi ville skulle vi kunna skriva {1 + 2}, komponenten skulle då skriva ut 3 i webbläsaren. 

Gå till din webbläsare oh kolla på hemsidan efter du uppdaterat AppHeader.

...

Nu står det bara "Welcome to", och inget mer. Varför?

...

Vi har inte skickat någon prop till vår komponent! Vi fixar detta enkelt genom att följande:

class App extends Component {
render() {
return (
<div className="App">
<AppHeader welcome="Agero" />
<AppIntro />
</div>
);
}
}

Om du tittar på webbsidan nu så bör det stå "Welcome to Agero". Notera också att precis som AppHeader, så är App också en komponent där vi kan evaluera uttryck. Vi kan t.ex. skicka ned en till prop som ett uttryck:

class App extends Component {
render() {
return (
<div className="App">
<AppHeader
welcome="Agero" date={new Date(Date.now()).toLocaleString()} />
<AppIntro />
</div>
);
}
}

Vi uppdaterar även AppHeader:

const AppHeader = (props) =>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to {props.welcome}, the current date is {props.date}</h2>
</div>;

Kolla på webbsidan igen och du bör se dagens datum, utöver det vi såg innan.

Detta är ett vanligt mönster i React, att ha en komponent som räknar ut något, och sen skicka vidare den datan man räknade ut till en komponent som presenterar datan. I vårt fall så tar App reda på dagens datum, skickar ned det tilll AppHeader som presenterar det. Här är hela vårt nuvarande program:

import React, { Component } from "react";
import logo from "./logo.svg";
import "./App.css";

class App extends Component {
render() {
return (
<div className="App">
<AppHeader
welcome="Agero"
date={new Date(Date.now()).toLocaleString()}
/>
<AppIntro />
</div>
);
}
}

const AppHeader = props =>
<div className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<h2>Welcome to {props.welcome},the current date is {props.date}</h2>
</div>;

const AppIntro = () =>
<p className="App-intro">
To get started, edit <code>src/App.js</code> and save to reload.
</p>;

export default App;

 

Om du går tillbaka till din webbsida nu så kommer du att märka något konstigt: tiden uppdateras inte. Tiden är alltid den samma som tiden var när vi uppdaterade sidan. Vi kommer titta mer på detta i nästa avsnitt när vi pratar om Klasser och komponenter med state!

  

Är du sugen på att bli en av oss? Läs om vår företagskultur eller lämna in en spontanansökan.

Läs om vår företagskulturJag vill också bli kollega

Publicerad: 2017-08-18