-
Notifications
You must be signed in to change notification settings - Fork 10.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Question] Pass props from page to layout #2112
Comments
You could pass a prop to the pages that you could call from them e.g. render () {
return <div>
{ this.props.children({...this.props, updateLayoutFunction }) }
</div>
} You'd then update the layout state and re-render. |
Whilst that does work it definitely isn't clean... and close to an anti-pattern... |
Layout components are the parents to page components so not sure why you think pages should pass props to layouts. |
I'm attempting multilingual support, so being able to pass certain pieces such as the different translations would be very helpful. |
I am also interested to pass a context to layouts, I would pass it from We could use multiple layouts files like here: #1895 |
yeah, when you pass context when you create a layout https://www.gatsbyjs.org/docs/bound-action-creators/#createLayout |
Thanks Kyle, that will help a lot.
…On Sep 23, 2017 10:08, "natural data corruption" ***@***.***> wrote:
How can I pass a method as a prop from a layout to this.props.children ?
I named my method updateLayoutFunction but
{ this.props.children({...this.props, updateLayoutFunction }) }
returns "ReferenceError: updateLayoutFunction is not defined."
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<#2112 (comment)>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AH_TYXMR4P-ghsLYWRtOx29Wsq1QsmDVks5slLx2gaJpZM4PXbM_>
.
|
@KyleAMathews at that point, is it aware of the path though? I take it probably not? |
Which point? When creating a layout? No — you'd need to pass it data keyed by path. Easier probably to use the "parent passes a callback function to child" pattern though. |
@KyleAMathews yea i assumed so. We've already began to work towards that approach. |
@KyleAMathews @davidhouweling I have a header component in the layout, and when clicked on the labels on the header inside the layout, I want the page to scroll, for this, I need to pass some data to the header component inside the layout. Please guide me through it. Thanks. |
I'm trying to pass props to children like this: render () { { this.props.children({...this.props, updateLayoutFunction }) } however, I get the error that updateLayoutFunction is not defined, no matter where and how I try to define it. Could you please tell me how can it be defined? |
assuming updateLayoutFunction is a method of parent component, you can do something like this:
|
Thanks, man. You saved my life. |
One thing to keep in mind with the approach, it only appears to render the update to the layout on the client side. It does not put it into the statically generated html file. As a result I moved away from using the layout solution all together. We ended up creating a component which is applied via the page template as a root component of the template. |
Thank you for the information. I didn't test it on the statically generated site. It seems that I will have to move away from the layout solution too. |
I have a state variable on the template component which is passed as props to the template children, however when the state is updated, the props that is passed to the children does not update? Is this a bug? The only way I could get this to work is by setting the state variable as a key property on the template component, so when it changes it forces react to unmount and and mount the template again updating the props that is passed to the children. Anyone else got a solution for this? |
@davidhouweling can you share your solution? |
I need to pass the state from index.js to submit.js. The state contains a user input which is an ID required to make an API call in the submit.js. How do I pass the state from index.js to submit.js? |
|
|
I think you should add layout: false render () {
return <div>
{ this.props.children({...this.props, layout: false, updateLayoutFunction }) }
</div>
} |
In order to make this work, component composition can be implemented as an alternative solution. 1)Create a layout at
2)Create a page at
|
Anyone has a solution ? |
Due to the high volume of issues, we're closing out older ones without recent activity. Please open a new issue if you need help! |
I had a similar issue where I moved my base component This was easy to render as the root component of my various page layouts and pass whatever props I wanted into it (like page title) but then it became apparent than when switching routes everything was being unmounted and re-rendered, causing the state in There is a section: https://www.gatsbyjs.org/docs/layout-components/#how-to-prevent-layout-components-from-unmounting But it gives a solution without mentioning how to communicate between this component and the rest of the app. The I've ended up doing this but not sure if I haven't understood Gatsby properly as it feels like a hacky solution to something that everyone must come across when making an app: export const wrapPageElement = ({ element, props }) => {
return (
<Application {...props}>
{(state, dispatcher) =>
React.Children.map(element, child => React.cloneElement(child, { state, dispatcher }))
}
</Application>
);
}; Maybe a better solution will be to move the |
I understand that the purpose of layouts is that it should be shared across all the pages. But there needs to be a way to send customisations from a page itself to the layout so you can do things like highlight certain elements in the header for example.
At the moment the only way is to embed the page variations into the layout itself and check the
location.pathname
which really isn't appropriate.The text was updated successfully, but these errors were encountered: