오늘은 노마드코더 ReactJS 스터디 다섯 번째 날입니다! 오늘도 화이탱!
props is a way of sending data from a parent component to a child component
not a good way - as you are copying and pasting the same thing, better to have the same component and change only the text in the button
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function SaveBtn(){
return <button style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>Save Changes</button>
}
function ConfirmBtn(){
return <button style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>Confirm</button>
}
function App(){
return(
<div>
<SaveBtn />
<ConfirmBtn />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
use the same function but configure only the text
rending would mean Btn({banana:"Save Changes"})
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//props is the property given to the button
//whatever props you send to the Btn component will be put in the first argument of the Btn function
// == props will go into the object and will be given in the first argument to the component
function Btn(props){
return <button style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{props.banana}</button>
}
function App(){
return(
//value of the banana will be "save changes" and "continue"
<div>
<Btn banana="Save Changes" />
<Btn banana="Continue" />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
don't use props that much --> following is the same code from above without using props as an argument
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//props is the property given to the button
//whatever props you send to the Btn component will be put in the first arguement of the Btn function
// == props will go into the object and will be given in the first arguement to the component
function Btn({banana}){
return <button style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{banana}</button>
}
function App(){
return(
//value of the banana will be "save changes" and "continue"
<div>
<Btn banana="Save Changes" />
<Btn banana="Continue" />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
we can add more argument in the object
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//props is the property given to the button
//whatever props you send to the Btn component will be put in the first arguement of the Btn function
// == props will go into the object and will be given in the first arguement to the component
function Btn({banana, big}){
return <button style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontSize: big ? 18 : 15,
}}>{banana}</button>
}
function App(){
return(
//value of the banana will be "save changes" and "continue"
<div>
<Btn banana="Save Changes" big={true} />
<Btn banana="Continue" />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
using React.useState to change the content of the button
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//props is the property given to the button
//whatever props you send to the Btn component will be put in the first arguement of the Btn function
// == props will go into the object and will be given in the first arguement to the component
function Btn({banana, onClick1}){
return <button
onClick={onClick1}
style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{banana}</button>
}
function App(){
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Changes");
return(
//if I put onClick in the function Btn, then it is an eventlistern, the onClick in the custom component Btn/ is not an eventlistener, this is just a prop even though the name might be the same
<div>
<Btn banana={value} onClick1={changeValue}/>
<Btn banana="Continue" />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
we don't want to re-render if the prop doesn't change
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//props is the property given to the button
//whatever props you send to the Btn component will be put in the first arguement of the Btn function
// == props will go into the object and will be given in the first arguement to the component
function Btn({banana, onClick1}){
console.log(banana,"was rendering")
return <button
onClick={onClick1}
style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
}}>{banana}</button>
}
const MemorizedBtn = React.memo(Btn)
function App(){
const [value, setValue] = React.useState("Save Changes");
const changeValue = () => setValue("Revert Changes");
return(
//if I put onClick in the function Btn, then it is an eventlistern, the onClick in the custom component Btn/ is not an eventlistener, this is just a prop even though the name might be the same
<div>
<MemorizedBtn banana={value} onClick1={changeValue}/>
<MemorizedBtn banana="Continue" />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
output change from
to
using 'propTypes' to define the proptypes
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
function Btn({banana, fontSize}){
return <button
style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontSize,
}}>{banana}</button>
}
Btn.propTypes = {
banana: PropTypes.string,
fontSize: PropTypes.number,
}
function App(){
return(
<div>
<Btn banana="Save changes" fontSize={18} />
<Btn banana={14} fontSize={"Continue"} />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
output : we see an error in the console as fontSize for the second Btn is not a number and banana is not a string (UI works find)
giving values to the ones that are not defined
<!DOCTYPE html>
<html>
<body>
<div id="root"></div>
</body>
<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.production.min.js"></script>
<script src="https://unpkg.com/prop-types@15.7.2/prop-types.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<script type="text/babel">
//you can give default values if it is not defined (ex. fontSize)
function Btn({banana, fontSize=5}){
return <button
style={{
backgroundColor: "tomato",
color:"white",
padding: "10px 20px",
border: 0,
borderRadius: 10,
fontSize,
}}>{banana}</button>
}
Btn.propTypes = {
banana: PropTypes.string.isRequired,
fontSize: PropTypes.number.isRequired,
}
function App(){
return(
<div>
<Btn banana="Save changes" fontSize={18} />
<Btn banana="Font size is 5" />
</div>
);
};
const root = document.getElementById("root");
ReactDOM.render(<App/>, root);
</script>
</html>
first option of applying button color is making a css file and importing that css file in index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import "./styles.css";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
style.css file
button {
color: white;
background-color: tomato;
}
if we import the css that will be applied to all the buttons in every file
option 2 - we cound manually include the style in javascript code
import PropTypes from "prop-types";
function Button({text}) {
return <button style={{
backgroundColor:"tomato",
color:"white",
}}>{text}</button>;
}
Button.propTypes= {
text: PropTypes.string.isRequired,
};
export default Button;
option 3 - the best option is to make a module.css and import styles in the javacript, create a class, and apply the style
import PropTypes from "prop-types";
import styles from "./Button.module.css";
function Button({text}) {
return <button className={styles.btn}>{text}</button>;
}
Button.propTypes= {
text: PropTypes.string.isRequired,
};
export default Button;
css file would have a class and the css file name will be Button.module.css
.btn {
color: white;
background-color: tomato;
}
making another css file named App.module.css (the name doesn't matter however needs to end with .module.css)
.title{
font-family: Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif;
font-size: 18px;
}
App.js would contain the classname as styles.whateverclassname
import Button from "./Button";
import styles from "./App.module.css";
function App() {
return (
<div><h1 className={styles.title}>Welcome back!!!</h1>
<Button text={"Continue"} />
</div>
);
}
export default App;
the output