if i write yield like this in application.html.slim , the other components will render out of the layout component
doctype html
html
head
title
| Quiver
= javascript_pack_tag 'application'
= csrf_meta_tags
body
= react_component('ApplicationLayout',{logo: asset_path('logo'))
= yield
Here is the description with a picture .

so ,is anybody can teach me how to do that? thanks .. :(
I think there is some ways to do that.
(1) If you want to write the layout by using React Component, you should render your contents in the layout component. In this case, all props should be passed to the Layout componet at first and then you can pass some props to the child components.
<ApplicationLayout>
<YourContent />
<ApplicationLayout/>
(2) You can also write the layout by slim and render some React components into it.
body
header your header
div
main
= react_component('YourContent')
aside your aside
footer your footer
I want it works like the first way but written by the second😂 .It makes me sad there's no option in react_component helper which supports insert a component to another . However I solved this by writing ApplicationLayout Component in every slim page . That is the first way you mentioned .
but written by the second
by writing ApplicationLayout Component in every slim page
Why?
insert a component to another
I don't think it's a responsibility of this gem. I want to keep this gem simple and if you want more complex one, you can use react_on_rails.
I think rendering a component in another isn't a responsibility of this gem but a responsibility of React itself. In my app, I'm always rendering App component in server side. Router is a component for client-side routing.
render component: 'App', props: props
function App(props) {
const store = buildStore(props);
return (
<Provider store={store}>
<Router />
</Provider>
);
}
by writing ApplicationLayout Component in every slim page
Oh, at least you don't need to write a layout in every slim page. How about this?
# application.html.slim
(snip)
body
header your header
div
main
= yield
aside your aside
footer your footer
# foo.html.slim
= react_component('YourContent')
I didn't describe it clearly .
The requirements and descriptions are :
application.html.slim .It's something like this :
In application.html.slim .
// If there is some helper can supply a yield in component .
// For example , there is a helper named react_component_with_yield .
= react_component_with_yield 'AppLayoutComponent'
In Rails Controller FooController.rb
class FooController < ApplicationController
def bar
@component_data = [];
end
end
In app/views/foos/bar.html.slim:
= react_component 'BarComponent'
And the Component looks like :
AppLayout.js
... ...
import { Layout } from 'antd'
const {Content , Header ,Sider } = Layout
const AppLayout = () => {
return(
<Layout>
<Header>
header
</Header>
<Layout>
<Sider/>
<Content>
// I want BarComponent to be here .
// I know is wired but it's the only way i could thinkout
// for example , there is a flag called rails_yield
rails_yield
// every slim-page where react_component helper is called will insert here .
// repeat once again , i know it's wired ,but how can i make the Layout in application.html.slim to be a Component ?
</Content>
</Layout>
</Layout>
)
}
If i use the way u suggest , like :
header
| this is header
section
= yield
It means that the layout is simple HTML TAGS but not react components . Also means that I can not use AntDesign's Layout components ... :(
Or . I have to import AppLayout Components in every Component Like This :
... ...
import AppLayout from './AppLayout'
const BarComponent = () => {
return (
<AppLayout>
<div>
bar bar bar
</div>
</AppLayout>
)
}
:(
Maybe it is the problem of my project-structure-design . It's a very old and large project , hard to refactor .
I think U are right . The react-rails gem is simple and easy to use . I have tried the rails_on_react , it's too complex for me .
I will keep importing AppLayout Components in every Component to keep development schedule until I find A better way . Or refactor the structure-design .
Thanks .
The way I see it a potential solution is that you sniff the ant design rendered HTML. After all React is rendered out to simple HTML tags. So you grab the ant design HTML structure, add ant design CSS to your layout and then use the React components where they are necessary.
@qxchen6
"Simplest" though definitely not best practice:
Create a layout ReactComponent which renders passed in HTML in a prop as dangerouslySetInnerHTML.
Again, not best practice.
= react_component("ReactLayout", content: yield)
class ReactLayout extends React.Component {
render() {
return <div dangerouslySetInnerHTML={{ _html: this.props.content }}>
</div>
}
}
On second thought, yield might not work as is. If it doesn't try render_to_string(partial: "yield") then have a app/views/application/_yield.html.erb which just contains yield.
Going to close this to cleanup open discussions.
Most helpful comment
I didn't describe it clearly .
The requirements and descriptions are :
application.html.slim.It's something like this :
In
application.html.slim.In Rails Controller
FooController.rbIn
app/views/foos/bar.html.slim:And the Component looks like :
AppLayout.js
If i use the way u suggest , like :
It means that the layout is simple HTML TAGS but not react components . Also means that I can not use AntDesign's Layout components ... :(
Or . I have to import AppLayout Components in every Component Like This :
:(
Maybe it is the problem of my project-structure-design . It's a very old and large project , hard to refactor .
I think U are right . The react-rails gem is simple and easy to use . I have tried the rails_on_react , it's too complex for me .
I will keep importing AppLayout Components in every Component to keep development schedule until I find A better way . Or refactor the structure-design .
Thanks .