Well I don't know if I am allow to post a question like this which is obviously more generic. But I just wanted to clarify and understand more about React reusable components. I have a component which holds information to open modals, and to insert user input.
I wanted to create the same component - when it comes to the design - but instead of having inputs and modals I just wanted to display information.
Is it possible for me to use the same visual component with different purposes such as to Input data and Visualize data? How would I do that since the input and the modal component uses logic and its internal state to open modals and uses methods from its parent to handleInputData? how do I switch these functionalities?
Yes, of course. It's the core feature of React, the declarative composition of components.
For instance, let's say that you have a Modal component which handles the display of something on the screen, above other content. You can use the props to customize what it renders right?
Them, you will specialize that component with your different behaviours, like a form or displaying information.
Example (conceptually):
const Modal = ({ title, children }) => (
<div className="modal">
<h1>{ title }</h1>
<div className="body">
{ children }
</div>
</div>
)
const FormModal = () => (
<Modal title="What's your name?">
<form>
{ /* your form here */ }
</form>
</Modal>
)
const AlertModal = () => (
<Modal title="Something happened">
{ /* your information to display here */ }
</Modal>
)
Related
I am completely new to react. I created a component like this:
import React from "react"
function Product(props) {
return (
<div>
<h2>{props.product.name}</h2>
<button onClick={() => document.querySelector(".desc").style.display="block"}>More info</button>
<p className="desc" style={{display: "none"}}>{props.product.price.toLocaleString("en-US", { style: "currency", currency: "USD" })} - {props.product.description}</p>
</div>
)
}
export default Product
Then I render a few of the components in the App. The purpose of the button is that it should show the information about the specific component. However this way, Im always selecting the first element with "desc" class name.
How to select the element from the current component easily?
How to select the element from the current component easily?
You wouldn't do it like that with react. The way to alter what your app shows is to alter the state. Create a component that has state that reflects what should be rendered. Then when an interaction happens (e.g. a button click) alter the state. React will re-render and show your app according to the new state:
function Product(props) {
// create a state that holds the information if details should be displayed
// we initially set it to false
const [showDetails, setShowDetails] = useState(false);
// create a callback that toggles the state
// we will pass that to the onClick handler of our button
const handleToggleInfo = () => setShowDetails(current => !current);
return (
<div>
<h2>{props.product.name}</h2>
<button onClick={handleToggleInfo}>More info</button>
{showDetails && (
/* this will only get rendered if showDetails is true */
/* you don't need any css to "hide" it, it will just not render in the first place */
<p className="desc">
{`${props.product.price.toLocaleString("en-US", {
style: "currency",
currency: "USD"
})} - ${props.product.description}`}
</p>
)}
</div>
);
}
Generally speaking it isn't necessary with react to select DOM elements and alter them. This is all handled by state updates and re-rendering the components. A component describes the DOM given a current state and props. If you want your DOM to change describe that with state and props.
If you are not familiar with state in react you should really search for a good tutorial that covers that. It is a basic core concept of react. Without it you will not be able to create an app that has interactivity.
Tip: If you want to display a string that is constructed from multiple parts use template strings.
This is not reactish, you need to leverage your UI changes to the state
function Product(props) {
const [isDescVisible, setIsDescVisible] = useState(false);
return (
<div>
<h2>{props.product.name}</h2>
<button onClick={() => setIsDescVisible(true)}>More info</button>
{isDescVisible &&
<p className="desc">
{props.product.price.toLocaleString("en-US", { style: "currency", currency: "USD" })} - {props.product.description}
</p>
}
</div>
)
}
I'm very very new with React. Actually I started to learn today.
I want to build a single sidebar component in a website.
I toggle a sidebar using UseState and a function called openHandler that verifies of the sidebar is already active.
I'm wondering how should I approach the toggle inside of the sidebar. How should I change the state of the sidebar if all the handle is done in the main file (App.js)
I'm really sorry if this question don't make sense.
Here is a SandBox example of what I'm talking about.
https://codesandbox.io/s/hopeful-framework-c4k1h
If someone know what should I learn to play with that would be great.
Thanks in advance
you can pass the main handler to sidebar via props and bind it to insider toggle.
appjs
...
<CartBox openHandler= {openHandler} className={ToggleCartState} />
...
cartBox.js
...
<Toggle click={props.openHandler} />
...
Nice to read https://reactjs.org/docs/lifting-state-up.html
I assume you want to be able to change the state of the sidebar by clicking a button from another sibling / child of a sibling component.
if that's the case you'll need to put the useState hook in the higher level parent, then pass the state / an it's setter method as a prop to the children that will use it.
here is an example of what I mean.
Parent Component
function parent() {
// the sidebar state
const [sidebar, setSidebar] = useState(false);
// helper function that toggles state
function toggle() {
setSidebar(!sidebar);
}
return (
<section className="Parent">
{ /* Conditional Render */
sidebar ?
<Navbar stateManager={{toggle}} />
: <HamburgerIcon stateManager={{toggle}} />
}
</section>
)
Navbar / HumburgerIcon
function Navbar({stateManager}) {
// you now passed state and it's set method to the child
const {toggle} = stateManager;
return (
<div onClick={toggle}>
component content
</div>
}
You can put them all in same file and still do the same thing.
i'm rebuilding my portfolio with ReactJS as i'm learning this new language and i have 1 question. Should i use state or props only in a website where no content will need to be updated?
This is my main class:
class App extends Component {
state = {
name: 'My name',
job: 'Desenvolvedor Web'
}
render() {
return (
<div className="App">
<Header name={this.state.name} job={this.state.job}/>
</div>
);
}
}
And this is my Header.js
const Header = (props) => {
return(
<div className="Header">
<div className="conteudo text-center">
<img src="" className="rounded img-circle"/>
<h1>{props.name}</h1>
<h2>{props.job}</h2>
</div>
)
}
I guess my entire one page portfolio will follow this structure path, with not a big use of handles and changes in my DOM.
I'm sorry for this noob question, i'm really trying my best to learn React.
You should use both state and props in conjunction with one another. You're using both in your code perfectly fine. State is something that is managed by a component and can be passed down to a child via the props. A simple way of understanding this is that you can pass down the Parent component's state (App) to the child (Header) in the form of props which is an important concept in React.
State is both readable and writable whereas props are read only. Also, any change in the components state triggers a re-render.
Here, your state acts as the top/root level for the data that can be passed down to other components if it needs to be used again.
See these for more info.
What is the difference between state and props in React?
https://flaviocopes.com/react-state-vs-props/
State is for properties of your component that change and in turn cause your component to re-render. If you are only passing data down to read, props are a more appropriate choice.
I'm trying to have popup window with YouTube video that not affect the main page.
I can still interact with the main page, similar on this web site when you click track you have small popup video on right bottom corner.
I have App.js with YouTube API
{
getYouTubeApi = (searchTerms1, searchTerms2) => {
fetch(`https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=10&q=${searchTerms1} ${searchTerms2}&type=video&key=YOUR_KEY`)
.then(res=>res.json())
.then(data=>{
this.setState({videoId: data.items[0].id.videoId})
})
.catch(error=>console.log(error))
}
render(){
return (<YouTube opts={opts} videoId={this.state.videoId} />)
}
}
getYouTubeApi function I call on click on track that just bring to the top of my page where YouTube video loads.
Here is my school project.
Since this describes DOM behavior more than business logic, you could put in whatever you want in a specific component that behaves like a modal (whether by swapping out css classes or setting inline styles based on certain conditions).
To make this modal reusable, I'll suggest you make it a higher order component to wrap around <Youtube /> component or any other component you want to display with modals.
For example, you could have
const Modal = (ComponentToDisplayAsModal, props) => (
<div class="modal">
<ComponentToDisplayAsModal {...props} />
</div>
)
You could then style the modal class to behave like a modal.
On the view you wish to show your modal, you could render
Modal(Youtube, props)
I have built an element which is kind of template. (e.g, thumbnail container with image at the top and something in the footer with dynamic content between them)
the dynamic content can be different types of DOM elements, based on the state.
I did it with adding logic in the render method which "injects" the dynamic part.
Does this make sense (having logic in the render method which returns different react components)?
Is there a better way for templating? (i'm not looking for projects that add this capability, wanted to know if there's a "react way" to do so.
Thanks!
edit: here's the code I was referring to (coffeescript):
internalContent: ->
switch #props.title
when "title1" then SomeReactFactory(props)
when "title2" then SomeOtherReactFactory(props)
render ->
...
DOM.div
className: 'panel'
#internalContent()
the internalContent() method is dynamically adding some React Component based on the prop
This is the React way.. And you should make use of it to target your specific domain.
For example a Button in React could be written like this:
const MyButton = ({ text, type = "normal", color = "blue", onClick }) => {
return (
<button
onClick={onClick}
style={{backgroundColor: color }}
className={"my-button my-button--type" + type}>
{text}
</button>);
};
Or a layout component:
const MyLayout = ({side, nav, main}) => {
return (
<div className="container">
<nav>{nave}</nav>
<aside>{side}</aside>
<div className="main">{main}</div>
</div>
)
}
Now you can composite it for example like this:
class App extends Component {
...
render() {
<MyLayout
nav={<MyNav/>}
side={<MySideBar items={...} />}
main={<MyButton onClick={this.onClick} text="Main Button"}
/>
}
}
Dont try to pack everything in a big Component which will do everything, the trick in React is to make small reusable Components and composite them.
You could also create a bunch of components which you can use across many projects.