Rerender Layout from a page?

Hey Guys,

I’m not quite sure if my question might be more react or more redwoodjs related. I’m still a beginner when it comes to web development. Anyway I’m gratefull for any help or hint that solves my problem!

I have a layout DefaultLayout and a page MyPage .

My Routes.tsx looks something like this:

...
<Set wrap={DefaultLayout}>
   <Route path="/page" page={MyPage} name="mypage"/>
</Set>
...

I want DefaultLayout to rerender caused by an action (buttonclick etc.) on MyPage.

My original idea was to simply do this by changing the state of DefaultLayout. I wrote a function for this in DefaultLayout but I can’t see any way to pass this function to MyPage as the only connection between the Page and the Layout I can find is Routes.tsx

I discovered two things, which might be interesting, while searching for a solution:

1.I found something called Routing Params which are described in here (Routing Params | RedwoodJS Docs). I guess in my case using routing params wont work because they can only pass a string?

2.I thought that it may be enough to just rerender MyPage and then DefaultLayout would, as they’re connected, automatically rerender with it. But if I’m not mistaken the above lines of code resolve to something like this:

<DefaultLayout>
  <MyPage/>
</DefaultLayout>

So MyPage is a child of DefaultLayout and rerendering the page should not automatically cause the Layout to rerender.

As I said I’m gratefull for any Idea! Maybey im just thinking of it the wrong way or I’am missing important WebDev or react knowledge for this.

What is in your layout that from a UX perspective would render when something inside it is clicked?

Layouts are like wrappers. They are good for consistent ui across many routes like headers and navigation menus and footers and SEO.

See Layouts | RedwoodJS Docs

Maybe instead you want a component to render instead?

Perhaps if you describe in words what a user does and you want to see happen we can help.

For example, when a user clicks notification button a drop down menu lists their current notifications list.

I use Layouts to pull in themes and things that are the same in all the pages that share the layout – it wraps it’s contents in Theme and Context providers – it’s got its own state and re-draws when that changes (my layouts don’t have any visible UI, all visible content is from pages and components) so - which theme to use, what config to pass in context, etc… Note that my theme and config is set based on recognizing Url fragments - once it’s set it doesn’t really change.

You’d have to store something in state in the Layout if you want it to re-render

I use pullState to avoid Redux – pullstate - npm

1 Like

Thanks for your reply!
MyPage provides the possibility to send a message to another user. I use a simple form for this. Default Layout contains something like a Notification Bell which is placed in the top right corner of the page. The bell should be part of multiple pages which was the reason I put it in the Layout. Attached to the Bell is a number which shows the amount of unread messages a user has received. The final goal would of course be that the number increases automatically when a new message arrives. For testing reasons I’m sending messages to myself (meaning from the user that is currently logged in to the user that is currently logged in). I wanted to achieve that as soon as I press the submit button on MyPage, the Layout and the bell are rerendered. I wanted to see if my code was working properly and the number attached to the bell increases. As already said thats not how it should work forever;-)

What u wrote about layouts was easy to follow. So to put it in a nutshell: Layouts are used for static ui. When it comes to something like my notification bell I should rather create a independent component and integrate this component into the my pages, right?

This is a perfectly valid use case for layouts. The solution to your problem is what @ajoslin103 is saying he does - put your state in a React Context, or a global state management library. I’d recommend to start with Context until you run into some kind of limitation with that solution. When you do you can look at a more advanced global state management library.

The way to have a Context available for both your layout and your page is to do this:

<Set wrap={[MessageContext, DefaultLayout]}>
   <Route path="/page" page={MyPage} name="mypage"/>
</Set>

If you’re new to Contexts I’d recommend reading some random intro blog post. Then read this: How to use React Context effectively. But don’t do all that complicated dispatch stuff he does. As he says himself, it’s probably enough with just useState in a lot of cases. So start with that.

1 Like