How to pass variables and functions to components in react? - reactjs

I want to create a component and call each instance with individual values. Each component (<NewRanger .../>) should also use a different handleChangeFunction. I pass this as follows: handleChangeFunction={handleChangeEm100} where handleChangeEm100 is the individual name of the function. This should then be taken over within the component as onChange={{handleChangeFunction}}. But somehow it crashes for me without any concrete error. Am I doing something conceptually wrong here?
function Check() {
const [valueEm100, setValueEm100] = React.useState([96, 99]);
const handleChangeEm100 = (event, newValue, activeThumb) => {
..
};
function NewRanger({valueName, valueRange, valueNameRange, handleChangeFunction,
steps, minV, maxV}) {
return (
<>
<div className='Text-EM-main'>
<div className="Text-EM-0">
{valueName}:
</div>
<div className="Text-EM-1">
{{valueRange}[0]}
</div>
<div className="Text-EM-2">
<Slider
getAriaLabel={() => valueNameRange}
value={{valueRange}}
onChange={{handleChangeFunction}}
valueLabelDisplay="auto"
getAriaValueText={valuetext}
disableSwap
step={{steps}}
marks
min={{minV}}
max={{maxV}}
/>
</div>
<div className="Text-EM-3">
{{valueRange}[1]}
</div>
</div>
</>
)
}
return (
<>
<NewRanger
valueName={"EM100"}
valueRange={valueEm100}
valueNameRange={'em100 range'}
handleChangeFunction={handleChangeEm100}
steps={1} minV={90} maxV={110}/>
</>
)

First of all never define you components in other components. Move NewRanger to outside of the Check component. Also you are using extra {} in your code. Here is the updated code:
function NewRanger({valueName, valueRange, valueNameRange, handleChangeFunction,
steps, minV, maxV}) {
return (
<>
<div className='Text-EM-main'>
<div className="Text-EM-0">
{valueName}:
</div>
<div className="Text-EM-1">
{valueRange[0]}
</div>
<div className="Text-EM-2">
<Slider
getAriaLabel={() => valueNameRange}
value={valueRange}
onChange={handleChangeFunction}
valueLabelDisplay="auto"
getAriaValueText={valuetext}
disableSwap
step={steps}
marks
min={minV}
max={maxV}
/>
</div>
<div className="Text-EM-3">
{valueRange[1]}
</div>
</div>
</>
)
}
function Check() {
const [valueEm100, setValueEm100] = React.useState([96, 99]);
const handleChangeEm100 = (event, newValue, activeThumb) => {
..
};
return (
<>
<NewRanger
valueName={"EM100"}
valueRange={valueEm100}
valueNameRange={'em100 range'}
handleChangeFunction={handleChangeEm100}
steps={1} minV={90} maxV={110}/>
</>
)

Related

how can i send an api call from the supreme function to another component called product to change a mock data called cart: true and display in cart

function Supreme(){
return (
<div>
<Meniu />
<Informatii />
<h1 className="title">Supreme</h1>
<Product myObj={supremeData}/>
<div className="numar">
<p >{supremeData.length} Products</p>
</div>
<Footer />
</div>
)
}
function Product (props) {
const Lista = [...props.myObj]
return (
<div className="product-list">
{Lista.map((produse)=>{
return(
<div className="produse" key={produse.id}>
<img src={produse.image} />
<h1>{produse.name}</h1>
<h2>{produse.price}</h2>
<button className="button-product">ADD TO CART</button>
</div>
)
})}
</div>
)
}
How can I send an API call from the supreme function to another component called product to change mock data called cart: true and display it in cart?
1- Define a method for handling api call in supreme component.
2- Pass it to Product component same as you did for "myObj" prop.
3- Call defined method when required event happened in product component.(for example: componentDidMount or onclcik)
function Supreme(){
cosnt [card , setCard]=useState({})
const method = (p)=>{
axious.post(p).then(res=> setCard(res)}}
return (
<div>
<Meniu />
<Informatii />
<h1 className="title">Supreme</h1>
<Product myObj={supremeData} apiCall={method}/>
<div className="numar">
<p >{supremeData.length} Products</p>
</div>
<Footer /></div>);}
And Product Component
function Product (props) {
const Lista = [...props.myObj]
return (
<div className="product-list">
{Lista.map((produse)=>{
return(
<div className="produse" key={produse.id}>
<img src={produse.image} />
<h1>{produse.name}</h1>
<h2>{produse.price}</h2>
<button onclick={()=>props.apiCall()}
className="button-product">ADD TO CART</button>
</div>
)
})}
</div>
)
}

while using map() function props.data is undefined

its shows data without map function in console
but whenever I use map function it shows props.data is undifned and also undifined in console
I have used the same code for another page and that works
const Test_Footer = (props) => {
console.log("ok", props.data)
const newvar =props.data.map((item) => {
return (
<>
<li>{item.data.id}</li>
</>
)
})
// console.log(newvar)
return (
<div>
<div class="main-content">
<footer className="footer">
<div className="review-checkbox"><input type="checkbox" /><label>Review</label></div>
<div className="question-nav">
<ul className="pagination">
{newvar}
</ul>
<button className="minimize-btn ml-10"><img src="images/minimize-btn.png" /></button>
</div>
</footer>
</div>
</div >
)
}
export default Test_Footer
const newvar = props && props.data && props.data.map((item) => {
return (
<>
<li>{item.data.id}</li>
</>
)
})

Button Flickering onHover in React

I have 2 Components "TableCard" et "TableGrouping". I have a component inside "TableCard" called "Grouping".
When I hover the button with my mouse it is flickering/flashing on my screen. The 2 components are separated in 2 files because I need to modify the content of "TableGrouping" in "TableCard" (when I put directly the content of grouping into "TableGrouping" it's working fine but it's not my objective.
Here is my code:
export function TableGrouping(props) {
return (
<div className="form">
<div className="row align-items-center form-group-actions margin-top-20 margin-bottom-20">
<div className="col-xl-12">
<div className="form-group form-group-inline">
<div className="form-label form-label-no-wrap">
{props.children}
</div>
</div>
</div>
</div>
</div>
);
}
export function TableCard() {
const Grouping = () => {
function BtnSupprimer(props) {
return <Button>test</Button>;
}
return (
<>
<BtnSupprimer/>
</>
);
};
return (
<TableGrouping>
<Grouping />
</TableGrouping>
);
}
Link of what it's doing : here
Do some of you have an Idea ? Thank you :)

How to pass Mobx store as props to react compoent

I have this app that uses mobx, in it there is a component called "Listings" that uses some state from mobx to render a list of items.
The way it is right now, is that the Listings component gets the data it needs(store.restaurantResults[store.selectedFood]) from inside of it by using the mobx store like so:
const Listings = () => {
const store = React.useContext(StoreContext);
return useObserver(() => (
<div className="pa2">
{store.restaurantResults[store.selectedFood] &&
store.restaurantResults[store.selectedFood].map((rest, i) => {
return (
<div key={i} className="pa2 listing">
<p>{rest.name}</p>
</div>
);
})}
</div>
));
};
But i think this is wrong, as it couples the component with the data, I want instead to pass that data via props so it can be reusable.
What is the correct way to do this? Right now my App looks like this, where it's being wrapped around a storeProvider:
function App() {
return (
<StoreProvider>
<div className="mw8 center">
<Header title="EasyLunch" subTitle="Find Pizza, Burgers or Sushi in Berlin the easy way"/>
<FixedMenu menuItem1={"Pizza"} menuItem2={"Burger"} menuItem3={"Sushi"} />
<p className="b tc pt3">or...</p>
<Search />
<Listings />
</div>
</StoreProvider>
);
}
My idea is to extract everrything inside the StoreProvider into another component that has a store and returns the jsx via useObserver so that I can acces the store and then pass what i need as props to the other components. like this:
const Wapper = () => {
const store = React.useContext(StoreContext);
return useObserver(() => (
<div className="mw8 center">
<Header title="EasyLunch" subTitle="Find Pizza, Burgers or Sushi in Berlin the easy way" />
<FixedMenu menuItem1={"Pizza"} menuItem2={"Burger"} menuItem3={"Sushi"} />
<p className="b tc pt3">or...</p>
<Search />
<Listings listings={store.restaurantResults[store.selectedFood]} />
</div>
))
}
And then on the listings component change the hard coded store.restaurantResults[store.selectedFood] inside to use the props that is being passes now, that is called listigs like so:
const Listings = ({listings}) => {
const store = React.useContext(StoreContext);
return useObserver(() => (
store.loading
? <Loading />
: <div className="pa2">
<div className="flex flex-wrap">
{listings &&
listings.map((rest, i) => {
return (
<div key={i} className="pa2 listing">
<img className='object-fit' src={rest.image_url} alt="restuarant" />
<p>{rest.name}</p>
<p>{rest.location.address1}</p>
</div>
);
})}
</div>
</div>
));
};
And this works, but is this the right way to go about this?
As <Listings/> can be provided with listing and loading you can:
const Listings = ({listings, loading}) => {
if(loading) return <Loading />
return (
<div className="pa2">
<div className="flex flex-wrap">
{listings && listings.map((rest, i) => {
return (
<div key={i} className="pa2 listing">
<img className='object-fit' src={rest.image_url} alt="restuarant" />
<p>{rest.name}</p>
<p>{rest.location.address1}</p>
</div>
);
})}
</div>
</div>
);
}
No observables used, no useObservable required.
You want to useObservables on store for listings then no reason to wrap all components with useObservable. You should wrap <Listings/> only.
I usually define my store as a global, so every component has visibility of it:
class Store {
#observable myVar
}
global.store = new Store()
And in my components i just use it:
#observer
export default class MyComponent extends React.Component {
constructor () {
super()
store.myVar = 0
}
setMyVar (a) {
store.myVar += 1
}
render () {
return <button onClick={this.setMyVar}>
Clicked {store.myVar} times
</button>
}
}

setting variables in a map function

I have a function that returns this jsx mixed with some code like this:
showMedia = () => {
return (
<div>
{
<div id="mainContent">
{props.files.map((file) =>
const ext = fileExtension(file.name),
const icon = fileIcon(ext),
const isImg = isImage(ext),
<div key={file.id}>
<DisplayResults
fileId={file.id}
downloadName={file.downloadName}
fileTitle={file.title}
isImg={isImg}
icon={icon}
ext={ext}
/>
</div>
)}
</div>
}
</div>
);
}
In my editor, it's saying that it is expecting an '{' for the const variables I am setting after .map
Am I not using the correct syntax?
Thanks!
Since you don't have a function body {} for your arrow function, it is expecting an implicitly returned expression.
Give it a function body and declare your variables and return the JSX instead:
showMedia = () => {
return (
<div>
{
<div id="mainContent">
{props.files.map(file => {
const ext = fileExtension(file.name);
const icon = fileIcon(ext);
const isImg = isImage(ext);
return (
<div key={file.id}>
<DisplayResults
fileId={file.id}
downloadName={file.downloadName}
fileTitle={file.title}
isImg={isImg}
icon={icon}
ext={ext}
/>
</div>
);
})}
</div>
}
</div>
);
};
You have to add "return" in map function because map always expect to return something, so your problem can be solved by adding this
{props.files.map(file => {
return (
<div key={file.id}>
{/* something */}
</div>
);
})}
Hope this help

Resources