How to access variable from parent component using JSX Namespacing in React - reactjs

I want to pass variable from parent component to props.children
Is posible if I access parent variable to props.children like this?
function App() {
return (
<div>
<Example>
<Example.Title>
<p>this is Title</p>
</Example.Title>
<Example.Body>
<p>this is Body</p>
<p>value from {parent}</p>
</Example.Body>
</Example>
</div>
);
}
export default App;
Parent Component
import { useState } from "react";
function Example(props) {
const [parent, setParent] = useState("parent");
return <div>{props.children}</div>;
}
Example.Title = (props) => <>{props.children}</>;
Example.Body = (props) => <>{props.children}</>;
export default Example;

You can't do it like this, because Example.Body component is already rendered when passed from App to Example.
Example must pass the "parent" prop to Example.Body
One solution is to use children as a render props (see it working there):
export default function App() {
return (
<div>
<Example>
{(parentParam) => (
<>
<Title>
<p>this is Title</p>
</Title>
<Body>
<p>this is Body</p>
<p>value from {parentParam}</p>
</Body>
</>
)}
</Example>
</div>
);
}
function Example(props) {
const [parent, setParent] = useState('parent');
return <div>{props.children(parent)}</div>;
}

Related

Toggle one component from another using React hook

I have a two child components and I want a button in one of them to toggle (on/off) the html in another. I have watched tutorials on lifting state up, and communication between components but most of it has to do with moving data. I want to manipulate a component from another. I would like the achieve this using useState, and without useContext if possible. Thanks!
THE PARENT
import React from "react";
function App() {
return (
<div>
<AppProvider>
<ComponentOne/>
<Slideshow />
<ComponentTwo/ >
</AppProvider>
</div>
);
}
CHILD 1
export default function ComponentOne() {
return (
<div>
<button>The button that toggles</button>
</div>
);
}
CHILD 2
export default function ComponentTwo() {
return (
<div>
<div>The content that hides/shows</div>
</div>
);
}
You need to use state to toggle the values. Pass the state to the ComponentTwo as props and pass the state updater function as the callback function to the ComponentOne as a prop.
import React , { useState, useCallback } from 'react';
function ComponentOne({ onToggle}) {
return (
<div>
<button onClick={onToggle}>The button that toggles</button>
</div>
);
}
function ComponentTwo({show}) {
return (
<div>
{show && <div>The content that hides/shows</div>}
</div>
);
}
export default function App() {
const [show, setShow ] = useState(true);
const handleToggle = useCallback(() => setShow(prevShow => !prevShow),[])
return (
<div className="App">
<ComponentOne onToggle={handleToggle} />
<ComponentTwo show={show} />
</div>
);
}
Refer
useState
useCallback

How to hide a component in react?

I have two components App component and the Component2
import Component2 from './Component2';
class App extends Component {
state={data:""}
changeState = () => {
this.setState({data:`state/props of parent component
is send by onClick event to another component`});
};
render(){
return (
<div className="App">
<Component2 data={this.state.data} />
<div className="main-cointainer">
<h2>Compnent1</h2>
<button onClick={this.changeState} type="button">
Send state
</button>
</div>
</div>
);
}}
export default App;
and the Component2.js
const Component2 = (props) => {
return (
<div className="main-cointainer">
<h2>Compnent2</h2>
<p>{props.data} </p>
</div>
)
}
export default Component2;
Here I am passing the data from App component to the Component2 component . What I want is to hide
the Component2 from being rendered while passing the data from App component to the Component2 component .
I tried writing this statement
{ false && <Component2 data={this.state.data} /> }
but this did not work out .
Any suggestions to achieve this type of requirement ?
To hide Component2 (without changing its functionality), add it in a div with style = {{display: 'none'}}
App.js
import React from "react";
import "./style.css";
import Component2 from "./Component2";
export default function App() {
return (
<div>
<h1>Hello StackBlitz!</h1>
<p>Start editing to see some magic happen :)</p>
<div style={{ display: "none" }}>
<Component2 myProps="this is a example" />
</div>
</div>
);
}
Check demo : https://stackblitz.com/edit/react-bbxgcr?file=src%2FApp.js
PS : Open the console to see the props in correctly passed to Component2
you can do this with only one if. If I understood the problem correctly
const Component2 = (props) => {
if(props.data === ""){
return(<div></div>)
}
return (
<div className="main-cointainer">
<h2>Compnent2</h2>
<p>{props.data} </p>
</div>
)
}
export default Component2;
Try using negation to simply convert an empty string into a boolean value.
{ !!this.stat.data && <Component2 data={this.state.data} /> }
When the this.stat.data is an empty string or falsy value then the Component2 will not render
Or
If you don't want to show display component on the page try this
<Component2 data={this.state.data} hidden={true}/>
Component2
const Component2 =({ data, hidden }) => {
return (
<div hidden={hidden}>
<h1>Component2</h1>
</div>
);
}
Adding hidden attribute on the HTML tag will hide the element on the page.

Prevent rerender of sibling component which initiates a useState in wrapper component

I am not very experienced with React but I have a very simple Setup.
export default function App() {
const [title, setTitle] = useState("still-empty");
const myFunction = title => {
setTitle(title);
};
return (
<div className="App">
<ComponentA myFunction={myFunction} />
<br />
<br />
<ComponentB title={title} />
</div>
);
}
const ComponentA = ({ myFunction }) => {
console.log("Rendering Component A");
return (
<div onClick={() => myFunction(Math.random() * 1000)}> Component A </div>
);
};
export default ComponentA;
const ComponentB = ({ title }) => {
return <div> Title : {title}</div>;
};
export default ComponentB;
Here is a sandbox to test this: https://codesandbox.io/s/musing-cookies-g7szr
See that if you click on "ComponentA", that exact ComponentA gets rerendered (you can see it in console) although no props are changed on this component. This is a simplified example of my real use case. In my real use case, ComponentA is a map where a lot of stuff (zoom, center)
will be reset. I want to prevent these resets and also the 1 second it takes for rerendering. Therefor I present this simplified example.
So how do I pass an information from ComponentA to ComponentB, without rerendering ComponentA itself? Thanks for helping out here.
use useCallback in Parent so that the function is not created again and again but only on initial render.
use React.memo so that when no props are changed the component wont re-render.
App
export default function App() {
const [title, setTitle] = useState("still-empty");
const myFunction = useCallback(title => {
setTitle(title);
}, []);
return (
<div className="App">
<ComponentA myFunction={myFunction} />
<br />
<br />
<ComponentB title={title} />
</div>
);
}
ComponentA
import React, { memo } from "react";
const ComponentA = ({ myFunction }) => {
console.log("Rendering Component A");
return (
<div onClick={() => myFunction(Math.random() * 1000)}> Component A </div>
);
};
export default memo(ComponentA);
Working demo is here:
https://codesandbox.io/s/affectionate-boyd-v7g2t?file=/src/App.js

React js Passing props to a component

Hello basically I need to pass some data to a component to be able to popular that component:
const Data = {
name: "a",
title: "b"
};
export default function App() {
return (
<Div className="App">
<Card name={Data.name} title={Data.title} />
</Div>
);
}
my card componen The component I need to receive data:
const Card = ({ props }) => {
return (
<div>
<h1>{props.name}</h1>
<p>{props.title}</p>
</div>
);
};
export default Card;
For some reason I am not getting these props on my card component
could someone help me with a solution to move props from a functional component to a functional component
example:
https://codesandbox.io/s/friendly-swanson-syuln
Your component declaration is wrong. You should only use brackets to destructure props, not for the entire props object.
const Card = (props) => {
just get rid of the curly braces around props in cards.js
import React from "react";
const Card = ( props ) => {
return (
<div>
<h1>{props.name}</h1>
<p>{props.title}</p>
</div>
);
};
export default Card;

Can I pass ref with function component?

-I am using function component.
-for now I am using 3 components here, from that One is parent component and another 2 are child components.
-I need to access one child component methods or state to another child methods. I already done with class components with CreateRef but for now I need to use with function components but I am getting Null inside 'ref.current'.
export function SideBySideList(props) {
const ref = React.createRef();
//this is call inside ListPage after sucess
function updateRightList(id) {
ref.current.state.actualSearchedModel.Id = id
ref.current.fetchDataAndUpdate();
}
function itemClicked(id) {
updateRightList(id);
}
return (
<>
<div className="col-12 no-padding">
<div className={props.leftListLayoutClass}>
<ListPage
updateRightList={updateRightList}
/>
</div>
<div className={props.rightListLayoutClass}>
<ListPage
ref={ref}
/>
</div>
</div>
<>
);
}
According to the official documentation:
You may not use the ref attribute on function components because they
don’t have instances
So if your ListPage is functional component, you have to convert it to the class component. Or your ref must refer to the DOM element inside of ListPage.
function ListPage ({ref}) {
return <div ref={ref}>Hello!</div>
}
UPDATED:
function ParentComponent () {
const [state, setState] = React.useState(null);
const onChildMount = React.useCallback((dataFromChild) => {
setState(dataFromChild);
});
return (
<div>
<pre>{JSON.stringify(state, null, 2)}</pre>
<ChildComponent onMount={onChildMount} />
</div>
)
}
function ChildComponent (props) {
const thisShouldBePassedToTheParent = "from child with love";
React.useEffect(() => {
props.onMount(thisShouldBePassedToTheParent);
}, []);
return (
<div>child component</div>
)
}
ReactDOM.render(<ParentComponent />, document.querySelector("#root"));
<script src="https://unpkg.com/react#16.9.0/umd/react.production.min.js"></script>
<script src="https://unpkg.com/react-dom#16.9.0/umd/react-dom.production.min.js"></script>
<div id="root"></div>
With functional components you can use refs like this:
// Import our hooks
import React, { useRef, useEffect } from 'react';
// create our ref
const myInput = useRef();
// This is equivalent to our componentDidMount, this will focus
useEffect(() => myInput.current && myInput.current.focus());
// Parse our ref to our textField
<Textfield inputRef={myInput} />
Here you can read docs https://reactjs.org/docs/hooks-reference.html#useref
Also you may use refs like this directly:
<TextField inputRef={input => input && input.focus()} />
You can read full Article here: https://medium.com/javascript-in-plain-english/react-refs-both-class-and-functional-components-76b7bce487b8
If someone looking for solution where Parent is class component and Child is functional component, and want to get data from child (state, function)
Class component:
class Parent extends React.Component {
constructor(){
this.setReferenceToElement = element => {
this.fromChild = element;
}
}
handleClick(){
console.log(this.fromChild());
}
render(){
return (
<div>
<Child setRef={this.setReferenceToElement} />
<button onClick={handleClick}> Get state from child </button>
</div>
)
}
}
Functional component:
function Child(props){
// ... it has some state
props.setRef(state => state);
return <div> Test </div>
}

Resources