How to pass props if it already has some value passed? - reactjs

function UpdatePngf(index, id) {
const [Cards, setCards] = props.value.Cards
let CardsData = Cards
var CardsObj = {
link: Cards[index].link,
icon: Cards[index].icon,
name: Cards[index].name,
png: Cards[index].png,
id: id,
}
CardsData[index] = CardsObj
setCards(CardsData)
}
export const UpdatePng = withUserData(UpdatePngf)
this is my function I want to pass props..but how I am supposed to do so??
should I do this way function UpdatePngf(index, id,props) {}? or other way
/** #format */
import React, { createContext } from 'react'
const UserData = createContext(null)
export const withUserData = (Component) => (props) => {
return (
<UserData.Consumer>
{(value) => <Component {...props} value={value}></Component>}
</UserData.Consumer>
)
}
export default UserData
This is my userData hoc..

I saw index, id also is props. You just update UpdatePngf:
function UpdatePngf({index, id, ...props}) { ... }
And pass props to UpdatePng wwhen using it: <UpdatePng id="...." index="..." ...yourProps>

Related

passing object using context and doing iteration with map

This is a simple question but I couldn't reach the final result after a lot of attempts. The problem is that I want to pass an object in context and use it in another file. And then do an iteration and create a specific element for each value.
App.jsx
const [activities, setActivity] = useState([
{
key: Math.random() * Math.random(),
name: 'Hello',
}
]);
const inputValue = useRef(null);
const addActivity = () => {
const activity = {
key: Math.random() * Math.random(),
name: inputValue.current.value,
};
setActivity(activities.concat(activity));
};
const value = {
// I want to pass this parameter - only activities has problem (Activity.jsx <h1>)
// I can't achieve activities.name in Activity.jsx
activities: [...activities],
functions: {
addActivity: addActivity
},
ref: {
inputValue: inputValue
}
};
<Context.Provider
value={value}
>
Context.js
export const Context = createContext();
Activity.jsx
const { activities, functions, ref } = useContext(Context);
return (
<section className="activity-container">
<input type="text" ref={ref.inputValue} />
<button onClick={functions.addActivity}>add!</button>
{
activities.map(activity => (
<h1>activity.name</h1>
))
}
</section>
);
I believe this is what you want:
// Sharing data through context
Context file:
// Context.js
import React, { useState, useRef, createContext } from "react";
export const DataContext = createContext();
const getRandom = () => Math.random() * Math.random();
const defaultValue = {
key: getRandom(),
name: "Hello"
};
const ContextProvider = ({ children }) => {
const [activities, setActivity] = useState([defaultValue]);
const inputValue = useRef(null);
const addActivity = () => {
const activity = {
key: getRandom(),
name: inputValue.current.value
};
setActivity([...activities, activity]);
};
const value = {
activities: [...activities],
functions: { addActivity },
ref: { inputValue }
};
return <DataContext.Provider value={value}>{children}</DataContext.Provider>;
};
export default ContextProvider;
Hook to read from context:
// useDataContext
import { useContext } from "react";
import { DataContext } from "./Context";
const useDataContext = () => {
const contextValue = useContext(DataContext);
return contextValue;
};
export default useDataContext;
Child Element where you want to receive the value from context:
// Child.js
import React from "react";
import useDataContext from "./useDataContext";
const Child = () => {
const data = useDataContext();
return (
<>
{data.activities.map((val, idx) => (
<div key={idx}>Name is {val.name}</div>
))}
</>
);
};
export default Child;
And the App container:
// App.js
import Child from "./Child";
import ContextProvider from "./Context";
export default function App() {
return (
<div className="App">
<ContextProvider>
<Child />
</ContextProvider>
</div>
);
}
I've created a sandbox for you to test.
You should make sure that the Activity.jsx component is wrapped with context provider, to get the proper value from the context.
I tried in this codesandbox, and it's working properly. You can refer to this and check what you are missing.

React Typescript Functional Component Syntax Error

I want to create a generic functional component but i get this :
Code block ;
interface IAppTable<Type> {
height: number;
data: Type[];
tableLayout: 'auto' | 'fixed';
pagination?: false;
}
const AppTable: <T>(props: IAppTable<T>) => React.FC<IAppTable<T>> = (props) => {
const [selectedRows, setSelectedRows] = useState<number[]>([]);
const getColumns = () => {
setSelectedRows([1]);
return [];
};
return <></>;
}
As explained by #Shrey, AppTable doesn't return a function component, it is a function component.
The React.FC type does not support generic components. This isn't a problem because anything that matches the signature of FC can be used as an FC. That signature is that it takes an object of props and returns a JSX.Element. FC automatically includes the children prop, but we can use the helper React.PropsWithChildren to add it ourselves.
We need to make the function itself generic, so we apply the types to the props and the return rather than to the function itself (which is what React.FC does, and why it cannot work with a generic).
import React, { useState, PropsWithChildren } from "react";
const AppTable = <T extends any>(props: PropsWithChildren<IAppTable<T>>): JSX.Element => {
const [selectedRows, setSelectedRows] = useState<number[]>([]);
const getColumns = () => {
setSelectedRows([1]);
return [];
};
return <></>;
}

ReactJs Functional Component - How to call function from outside?

How to call a function from outside of the functional component.
I have a functional component like this
import React, { useState } from 'react';
const Hello = () => {
// call updateField() here
};
const Headline = () => {
const [greeting, setGreeting] = useState(
'Hello Function Component!'
);
// Function inside Headline, I want to call this function in Hello()
const updateField = () => {
}
return <h1>{greeting}</h1>;
};
export default Headline;
I want to call updateField() in Hello() outside of Headline(). Please suggest.
Here are two ways to do this,
Method 1: Move the common state to a parent component
const ParentComponentWithHelloAndHeadline = () => {
const [field, setField] = useState()
const updateField = () => { ... }
return (
<>
<Headline field={field} updateField={updateField} />
<Hello updateField={updateField} />
</>
)
}
Method 2: Use React.Context (avoids prop-drilling, incase that is a concern using method 1)
const CommonContext = React.createContext({
field: 'commonField',
updateField: () => { ... }
})
const Hello = () => {
const { field, updateField } = useContext(CommonContext)
// call updateField() here
};
const Headline = () => {
const { field, updateField } = useContext(CommonContext)
const [greeting, setGreeting] = useState(
'Hello Function Component!'
);
return <h1>{greeting}</h1>;
};
export default Headline;
function RootApp() {
return (
<CommonContext.Provider>
<Headline />
...
...
<Hello />
</CommonContext.Provider>
);
}

Use react hook in HOC with passed params

I am trying to create HOC and use custom react hook inside. Also in order to use hook I need to pass paras to HOC, but I get error for use hook only in function body. My HOC is:
export const withUseAxisTranslate = (props) => {
const [t] = useAxisTranslate(props.namespace);
return (WrappedComponent) => (moreProps) => <WrappedComponent {...moreProps} t={t} />;
};
My useAxisTranslate looks like:
import { useSelector } from 'react-redux';
import { useTranslation } from 'react-i18next';
//This one is behave like regular i18 translate
//It returns like t() in array function and use axis name in order to find specific key by axis name
const useAxisTranslate = (namespace) => {
return [
(stringToTranslate) => {
const axisName = useSelector((state) => state.axisConfig.axis.name.toLowerCase());
const [t] = useTranslation(namespace);
return t(`${axisName}.${stringToTranslate}`);
},
];
};
export default useAxisTranslate;
My call to it is:
compose(
withWidth(),
withUseAxisTranslate({ namespace: 'header' }),
)(MyComponent);
The error I got is:
I have no idea why I get this error since I do not use classes here
Thanks for help
There are a few things to note here
You are trying to use useAxisTranslate which is meant to be a custom hook within withUseAxisTranslate which is not component but a function returning another function.
You are using useSelector and useTranslation in the custom hook inside of the the returned function which again violates the rules
The solution here is to correct both the things like below
export const withUseAxisTranslate = (props) => {
return (WrappedComponent) => (moreProps) => {
const [t] = useAxisTranslate(props.namespace);
return <WrappedComponent {...moreProps} t={t} />
}
};
and useAxisTranslate as
const useAxisTranslate = (namespace) => {
const axisName = useSelector((state) => state.axisConfig.axis.name.toLowerCase());
const [t] = useTranslation(namespace);
const translateFunction = (stringToTranslate) => {
return t(`${axisName}.${stringToTranslate}`);
};
return [
translateFunction
];
};
Try moving the useAxisTranslate hook inside the body of the component, like so
export const withUseAxisTranslate = (props) => {
return (WrappedComponent) => (moreProps) => {
const [t] = useAxisTranslate(props.namespace);
return <WrappedComponent {...moreProps} t={t} />;
}
};

React pass props when child component is a variable

How can I pass props to a child component when the component is a variable. In the following code, I need to pass the prev function as a prop to the step. Thanks.
import React, {useState} from 'react';
const Wizard = (props)=>{
const [step] = useState(0);
const CurrStep = props.steps[step];
const prev = ()=>{
console.log('prev called')
}
return (
<div>
{// need to pass prev as a prop to the CurrStep component}
{CurrStep }
</div>)
}
export default Wizard
Wizard.propTypes = {
header: PropTypes.func.isRequired,
steps: PropTypes.array.isRequired,//array of functional components
wizardContext: PropTypes.object.isRequired,
onComplete: PropTypes.func.isRequired
};
you can spread props inside the CurrStep component like this
return <CurrStep {...props} />;
here's a codesandbox demo of the code below
import React, { useState } from "react";
const Wizard = props => {
const [step] = useState(0);
const Comp1 = props => <div>{props.a}</div>;
const Comp2 = props => <div>{props.a}</div>;
const comps = [Comp1, Comp2];
const CurrStep = comps[step];
// this is just for demo, you can just pass props straight from Wizard
props = { a: "a", ...props };
return <CurrStep {...props} />;
};
export default Wizard;
This was my mistake, I was passing in an array like this:
[, ] instead of
[Step1, Step2]
Sorry to waste your time.
// adding (props) =>
const CurrStep = (...props) => props.steps[step](...props);
const prev = () => {
console.log('prev called')
}
return (
<div>
{CurrStep(prev)}
</div>
)

Resources