For naming convention for react javascript
files, always capital letter for the first letter!
e.g. App.js, Ninjas.js, AddNinjas.js etc...
Mostly App.js
, which is mainly gathering all the react materials, use legacy style (class style), but when it comes to Module type materials, you can use fucntional react style!
For conventional approach, you should create components
directory for other react modules.
But here we just goes same directory where App.js
is loacated.
You can just add import {Module Name} from {Module File Location}
statement for import other modules in App.js
For use these modules, you should export
or export default
from react module files.
then don't forget add the <Module Name />
in the render { return( )}
!
for more information about import
& export
! check this blog!
https://beomy.tistory.com/22 (Korean)
import React from "react";
import Ninjas from "./Ninjas";
import AddNinjas from "./AddNinja";
import "./App.css";
export default class App extends React.Component {
// ...
render() {
return (
//...
);
}
}
import React from "react";
import "./Ninjas.css";
const Ninjas = ({ ninjas, deleteNinja }) => {
//...
const ninjaList = ninjas.map((ninja) => {
return (
// ...
);
return
};
export default Ninjas;
import React from "react";
import Ninjas from "./Ninjas";
import AddNinjas from "./AddNinja";
import "./App.css";
export default class App extends React.Component {
state = {
ninjas: [
{ name: "Ryu", age: 30, belt: "black", id: 1 },
{ name: "Yoshi", age: 20, belt: "green", id: 2 },
{ name: "Crystal", age: 25, belt: "pink", id: 3 },
],
};
addNinja = (ninja) => {
// create ninja id inside object
ninja.id = Math.random();
// console.log(ninja);
// NOTE bad way!
//this.ninjas.push(ninja)
//this is carbon copy for the legacy list
let ninjas = [...this.state.ninjas, ninja];
this.setState({
ninjas: ninjas,
});
};
render() {
return (
<div className="App">
<h1>My first React app!</h1>
<p>Welcome :)</p>
<AddNinjas addNinja={this.addNinja} />
</div>
);
}
}
import React, { Component } from "react";
export default class AddNinja extends Component {
state = {
name: null,
age: null,
belt: null,
};
handleChange = (e) => {
this.setState({
[e.target.id]: e.target.value,
});
};
handleSubmit = (e) => {
e.preventDefault();
// console.log(this.state);
this.props.addNinja(this.state)
};
render() {
return (
<div>
<form onSubmit={this.handleSubmit}>
<label htmlFor="name">Name:</label>
<input type="text" id="name" onChange={this.handleChange} />
<label htmlFor="name">Age:</label>
<input type="text" id="age" onChange={this.handleChange} />
<label htmlFor="name">Belt:</label>
<input type="text" id="belt" onChange={this.handleChange} />
<button>Submit</button>
</form>
</div>
);
}
}
props
is data or state from other modules.
Here we add and update list from the data of other react materials.
First we have to check AddNinjas.js
!Let's look up the jsx
!
<form>
takes onSubmit
attribute for taking both click submit button and enter key action.Then, check the <input>
.
onChange
attribute, plus id
is important attribute.jsx
, use handleChange
method by this.handleChange
not this.handleChange()
. because if you call this.handleChange()
is executed when jsx
loaded. Since we want to run the method when input value changed, just type in this.handleChange
.handleChange
method update each target id: value
. so it will be name: {input value}
, age: {input value}
etc...state
to this.props.addNinja
!!But! what the heck is this.props.addNinja
means here?
Let's move on App.js
. then check the render()
!!
There is module <AddNinjas />
with attribute addNinja
!
Get that? so let's analyze this.props.addNinja
meaning!
this
is <AddNinjas />
modules, props
is attribute, addNinja
is attribute name!
So we sent our state
from AddNinjas.js
to <AddNinjas addNinja={ ... } />
.
Then what after? state
goes addNinja
method as an argument
, ninja
.
Ultimately, what we wanna do is add new state
from AddNinjas.js
to the state.ninjas
from App.js
But first, we don't have an id
in our new state
just like state.ninjas
. so we have to add new key
& value
pair by ninja.id = Math.random()
. random number is just for not using same id here.
as you may know, don't just push the stuff directly to our orginal state
. we have this.setState()
!
for setting new state
, we are not gonna push
the item directly but update!
so for updating, we have to bring whole data like this.
this.setState({[ { name: "Ryu", age: 30, belt: "black", id: 1 }, { name: "Yoshi", age: 20, belt: "green", id: 2 }, { name: "Crystal", age: 25, belt: "pink", id: 3 }, { name: ninja.name, age: ninja.age, belt: ninja.belt, id: ninja.id }, ]})
and this is so painful work if there is tons of data already in state
!
for avoiding this kind of shit work, there is awesome express [...data]
!
[...this.state.ninjas]
, this is carbon copy(C.C) for legacy list items.
[...this.state.ninjas, ninja]
, we just add newly generated state from AddNinjas.js
, ninja
after legacy items.
ninjas
for new list!setState()
for ninjas
, which is legacy list, equal to new list ninjas
.state = { ninjas: [ { name: "Ryu", age: 30, belt: "black", id: 1 }, { name: "Yoshi", age: 20, belt: "green", id: 2 }, { name: "Crystal", age: 25, belt: "pink", id: 3 }, { name: ninja.name, age: ninja.age, belt: ninja.belt, id: ninja.id }, ], }