Reputation: 155
I have a React Functional Component like this:
export const MyParentComponent = (props: Props) => {
const [myObjects, setMyObjects = React.useState< MyClass[] | undefined>(undefined);
//...
}
I have an array of 'MyClass' objects, in myObjects
and put that in the 'State' of React since that will affect MyParentComponent
rendering.
My question is how can I expose setMyObjects
method to class outside of MyParentComponent so that the caller can set a new array of MyObjects
and trigger a rendering of MyParentComponent ?
Upvotes: 0
Views: 1591
Reputation: 1138
since you want to change the state of MyParentComponent
in outside of that component, that outside component need to be a child, since you can need to pass the setMyObjects
function as a prop. In other way you can you react feature called Context API
to access the state of a component which is not Descendant.
React Context API
This is a simple scenario that elaborates how to change the state of the parent component inside the child component by passing setState function as a prop to child.
const Movie = () => { // This is the Parent component which render movies.
const movies = [
{ id: 1, title: "Batman", ratings: 8 },
{ id: 2, title: "Avengers", ratings: 8 },
{ id: 1, title: "Dune", ratings: 9 }
];
const [myObjects, setMyObjects] = useState(movies);
return (
<div>
{myObjects.map((movie) => (
<p>{movie.title}</p>
))}
<ChangeMovie changeMovieList={setMyObjects}/> // This is the child component which handle changing the state of Movie(Parent). Here pass the state change function as a prop(changeMovieList) to child. Then we can use that to change the state inside that component.
</div>
);
};
export default Movie;
const ChangeMovie = (props) => { // This is the child component.
const changeList = () => {
props.changeMovieList([ // here we change the state of Movie(Parent Component) inside child using the function passed.
{ id: 1, title: "Superman", ratings: 8 },
{ id: 2, title: "Titanic", ratings: 8 },
{ id: 1, title: "Fast & Furious 8", ratings: 9 }
]);
};
return (
<>
<button onClick={changeList}>Change Movie List</button>
</>
);
};
export default ChangeMovie;
Check this demo sandbox I created to elaborate this.
Upvotes: 0
Reputation: 557
If you want the parent component to be able to change the state, you'd either
myObjects
a state of the parent component ormyObjects
state with the props passed from the parent componentUnless having the state inside the component prevents you from making your component a pure component, I'd typically recommend the latter:
const {
useState
} = React;
const MyComponent = (props) => {
const [myObjects, setMyObjects] = useState(props.myObjects)
return (
<div>Rendering from MyComponent
<ul>
{myObjects.map(o => <li>{o}</li>)}
</ul>
</div>
);
};
const MyParentComponent = () => {
const objects = ['object1 from MyParentComponent', 'object2 from MyParentComponent', 'object3 from MyParentComponent'];
return (<MyComponent myObjects={objects} />);
}
ReactDOM.render( <MyParentComponent / > ,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root"></div>
Upvotes: 1