Should i use State or Props in this simple ReactJS page? - reactjs

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.

Related

What is this Component and how does it differ from others

I'm self-teaching React and was just wondering if someone could clear something up for me.
I have this component, which seems to be doing everything I need it to:
const Projects = ({ projectData }) => {
const { url } = useRouteMatch();
return (
{projectData.map((project) => (
<div className="project-container" key={project.id}>
<div className="project-image">
</div>
<div>
<h2>{project.name}</h2>
<p>{project.description}</p>
<div>
<Button class="button link_right relative" linkTo={`${url}/${project.id}`} btnText="Explore" />
</div>
</div>
</div>
))}
);
};
export default Projects;
While watching tutorials and reading documentation I'll typically see Function and Class Components but not whatever this is:
const ComponentName = () => {
So, my questions are:
What sort of component is my example known as
What purpose does it
serve when compared to a Function Component or a Class Component,
How would a Function Component or a Class Component need to look in
order to do everything that my example component is currently doing.
Thanks!
Making instance of class is too slow, because of calling constructor and inheritance. Functional components are just functions, there are no such overheads.
In addition, there is how to treat this. In class, entity of this is often unclear and that confused us. Arrow function reduce it, but using class, we must use this. this caused complicated management of state too. And class object has state itself, so it was troublesome.
Function, defined carefully, is easy to keep purity. It has no state itself. It means that state management is not bother us. Data flow is cleared.

React - Calling the function of other component

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.

When Reactjs has functional component as parent and child component as class

I am new in reactjs and learning bit and pieces. I am facing an issue. The scenario is like. I have a functional component as a parent. It has a child component as a class component. I would like to set or reset the child component's state on parent's button click. Or is there any way to call the child component's any method from the parent component. I tried as
// this call from a functional component.
<PhotoPreviewUploaend setSelectedFile={setSelectedFile} ref={setImagePreviewUrl} />
Later after a button click does this:-
setImagePreviewUrl('');
I read ref attribute allows access to the component. I tried this ref between 2 class component both parent and child is class components and it works as expected. But when did the same from a functional component it has no effect at all. How can I do it?
You are not embracing react one-way data flow by using refs like that; it might not behave the way you expect;
You should pass parent state handler logic function to the child component,
then child component call it with proper value; as the result your parent state will be updated and you have nice and clean one way data flow; you can use this in any kind of component, since you don't mess with this bindings in functional components;
This example demonstrates it in action:
function App() {
// Define your state
const [someState, setSomeState] = useState(0);
return (
<div className="container">
<Child parentCallback={setSomeState} />
</div>
);
}
class Child extends Component {
render(){
return(
<div>
<button
onClick={() => this.props.parentCallback(/*someValue*/)}
>
click me!
</button>
</div>
)
}
}

How to get react grand-child node to render when child is out of my control

I have a react component which uses a 3rd party library Component as a Child node. The Grand children (or the children of the 3rd party libary) are under my control. When my component receives new props it re-renders, however the 3rd party component seems to stop my components grand-children from re-rendering also, even though the props my component received, are passed to the non-re-rendering components directly
If I remove the 3rd party component then my component re-renders as do the grand-children.
render() {
<div>
<ThirdPartyComponent props={blah}>
{this.props.products.map(prod => <MyGrandChildrenComponents product={prod} />
</ThirdPartyComponent>
</div>
}
A concrete example can be found on this code sandbox: codesandbox.io/s/silly-grass-7frlx
I'd expect my MyGrandChildrenComponents component to get updated when this.props.products changes... Any hints?
This can happen if ThirdPartyComponent is a stateful component and is not handling its prop updates correctly. One way to force a re-render is to add a key prop to your ThirdPartyComponent and update its value when a re-render is needed.
render() {
<div>
<ThirdPartyComponent key={something-that-changes-when-rerender-needed} props={blah}>
{this.props.products.map(prod => <MyGrandChildrenComponents product={prod} />
</ThirdPartyComponent>
</div>
}
If ThirdPartyComponent is a PureComponent it should re render (and so re render its children) when one of its props changes so you can try:
render() {
<div>
<ThirdPartyComponent props={blah} products={this.props.products}>
{this.props.products.map(prod => <MyGrandChildrenComponents product={prod} />
</ThirdPartyComponent>
</div>
}
To trigger re renders when this.props.products changes.
But any prop should do.
If ThirdPartyComponent has a custom implementation of shouldComponentUpdate, then you will have to find the specific prop which triggers update if it exists.

When should I be using React.cloneElement vs this.props.children?

I am still a noob at React and in many examples on the internet, I see this variation in rendering child elements which I find confusing. Normally I see this:
class Users extends React.Component {
render() {
return (
<div>
<h2>Users</h2>
{this.props.children}
</div>
)
}
}
But then I see an example like this:
<ReactCSSTransitionGroup
component="div"
transitionName="example"
transitionEnterTimeout={500}
transitionLeaveTimeout={500}
>
{React.cloneElement(this.props.children, {
key: this.props.location.pathname
})}
</ReactCSSTransitionGroup>
Now I understand the api but the docs don't exactly make clear when I should be using it.
So what does one do which the other can't? Could someone explain this to me with better examples?
props.children isn't the actual children; It is the descriptor of the children. So you don't have actually anything to change; you can't change any props, or edit any functionality; you can only read from it. If you need to make any modifications you have to create new elements using React.CloneElement.
https://egghead.io/lessons/react-use-react-cloneelement-to-extend-functionality-of-children-components
An example:
main render function of a component such as App.js:
render() {
return(
<Paragraph>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}
now let's say you need to add an onClick to each child of Paragraph; so in your Paragraph.js you can do:
render() {
return (
<div>
{React.Children.map(this.props.children, child => {
return React.cloneElement(child, {
onClick: this.props.onClick })
})}
</div>
)
}
then simply you can do this:
render() {
return(
<Paragraph onClick={this.onClick}>
<Sentence>First</Sentence>
<Sentence>Second</Sentence>
<Sentence>Third</Sentence>
</Paragraph>
)
}
Note: the React.Children.map function will only see the top level elements, it does not see any of the things that those elements render; meaning that you are providing the direct props to children (here the <Sentence /> elements). If you need the props to be passed down further, let's say you will have a <div></div> inside one of the <Sentence /> elements that wants to use the onClick prop then in that case you can use the Context API to do it. Make the Paragraph the provider and the Sentence elements as consumer.
Edit:
Look at Vennesa's answer instead, which is a better explanation.
Original:
First of all, the React.cloneElement example only works if your child is a single React element.
For almost everything {this.props.children} is the one you want.
Cloning is useful in some more advanced scenarios, where a parent sends in an element and the child component needs to change some props on that element or add things like ref for accessing the actual DOM element.
In the example above, the parent which gives the child does not know about the key requirement for the component, therefore it creates a copy of the element it is given and adds a key based on some unique identifier in the object. For more info on what key does: https://facebook.github.io/react/docs/multiple-components.html
In fact, React.cloneElement is not strictly associated with this.props.children.
It's useful whenever you need to clone react elements(PropTypes.element) to add/override props, without wanting the parent to have knowledge about those component internals(e.g, attaching event handlers or assigning key/ref attributes).
Also react elements are immutable.
React.cloneElement( element, [props], [...children] ) is almost equivalent to:
<element.type {...element.props} {...props}>{children}</element.type>
However, the children prop in React is especially used for containment (aka composition), pairing with React.Children API and React.cloneElement, component that uses props.children can handle more logic(e.g., state transitions, events, DOM measurements etc) internally while yielding the rendering part to wherever it's used, React Router <switch/> or compound component <select/> are some great examples.
One last thing that worth mentioning is that react elements are not restricted to props.children.
function SplitPane(props) {
return (
<div className="SplitPane">
<div className="SplitPane-left">
{props.left}
</div>
<div className="SplitPane-right">
{props.right}
</div>
</div>
);
}
function App() {
return (
<SplitPane
left={
<Contacts />
}
right={
<Chat />
} />
);
}
They can be whatever props that makes sense, the key was to define a good contract for the component, so that the consumers of it can be decoupled from the underlying implementation details, regardless whether it's using React.Children, React.cloneElement, or even React.createContext.

Resources