How to pass Markdown file as this.props in React? - reactjs

I'm building a site in React using Redux, and my goal is to have a /pages folder full of markdown files that'll represent a pages content.
I have a React Container (smart) and a React Component (dumb) that'll be used to render the content. My thinking is that I'll import the markdown files to the parent container and pass them down to the child component to render them in the browser. I know I'll need to use something like markdown-it to convert the MD to HTML and maybe I'll need to use that in the child component.
My questions are:
1) How do I pass in markdown files from parent to child using this.props?
2) Am I on the right track? Is this the right way to go about it?
Here are my components:
Page Parent Container
import React from 'react'
import SamplePage from './../components/SamplePage'
export default class Page extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<section>
<SamplePage />
</section>
)
}
}
SamplePage Child Component
import React from 'react'
import { Link } from 'react-router'
export default class SamplePage extends React.Component {
constructor(props) {
super(props)
}
render() {
return (
<div className="page-container">
<Link to="/" className="previous-link">Go Back Home</Link>
// I want to render the MD here using {this.props.markdown}
</div>
)
}
}

A few things:
1) I recommend using a Markdown to JSX parser to keep your templating safe (otherwise you'd likely have to use dangerouslySetInnerHtml)
2) I'd run this parser during build time, so everything is already ready to go. If you're using webpack or browserify, you can add a custom loader/transformer function to look for *.md files being required and run it through the parser.
3) The parsed markdown is then simple JSX and can be required & dropped into your existing component as you've done above.

Related

How to wrap ALL components of react in a HOC?

ReactJS is a great library, However, it misses some features which I found in Vue and Angular. These features can be implemented of course in React, however, they require extra code to be written.
Every react component, or every JSX element I should say has the following properties shared, which are given by React to us to consume:
ref
key
I wanted to add extra props:
renderIf
fallback
These props help in a way I can't describe when it comes to conditional rendering and filtering the views based on the logged-in user permissions and roles (and other conditional rendering use cases, of course).
In react, if we wanted to apply these props to our components, we would use a HOC as follows:
// 🍎 Disclaimer: you don't have to understand any of the code written bellow, the general idea is that this is a HOC.
import React from 'react'
import getVal from './getVal'
export default function EnhancedComponent(OriginalComponent) {
return ({ renderIf: renderIf_ = true, override: override_, fallback: fallback_ = undefined, ...props }) => {
const renderIf = getVal(renderIf_)
const override = getVal(override_)
const fallback = getVal(fallback_)
const consumersComponent = <OriginalComponent {...props} />
let render = fallback
if (renderIf) render = consumersComponent
if (override_ !== undefined) render = override
return render
}
}
Where every time you want to apply these props to your components, you would have to wrap every new component you create with EnhancedComponent as follows:
export default EnhancedComponent(function Sidenav(){
return <div> side nav </div>
})
Now, you can use your Sidenav component within your App component as follows:
import Sidenav from './Sidenav'
export default function App(){
return (
<div>
<Sidenav renderIf={(5 + 5 === 10)}/>
<div>etc</div>
</div>
)
}
This API is great, but it has a drawback, which is, every time you want to apply these cool props (renderIf and fallback) you'll have to repeat these steps:
import Enhanced component to your file.
wrap your export with Enhanced component.
What I am looking for, is a method, or a way to inherit, or to add some props to the original react component class, somehow?
In react class components, I can imagine doing this on the React.Component class which we used to extend from in the past
class Car extends React.Component{
constructor(){}
render(){
return <div>I miss you 🌹</div>
}
}
But in react functional component, how can we do that?
I want to apply these props by default everytime I create a new component, without wrapping my components in a HOC everytime.
Does React have a way to do that? To change its defaults ?

can't extend react extended class

I have more than 20 components in my react project. So doing the same thing for every component would be so unwise, so from oop concepts if I create a class with all the functionalities, then I can use it for all the objects I want.
In my case, I want to check if a user is logged in or not. If not redirect to '/login'. Now I have 'NavigationBar' inside each component, where I'm writing some code to redirect or not. But for a few seconds I can see then snap of each components, especially those large ones.
This is not also wise step
So here is what I tried next, created a component named Core extending React.Component, then I extended all component from it, but it gives me error directly.
What is the actual problem here? How this can be solved?
codesandbox.io
just add this line to Child.js
import React from "react";
React doesn't allow creation of component by subclassing defined component, the only way to create component is to extends directly the React.Component class, But react allow you to add extra behavior to defined component by using Higher-Order Components which has purpose to alter defined component by adding wrapper to and existing component
function wrapper(WrappedComponent) {
return class extends React.Component {
render() {
// Here you can add any logic you want
return (<div>
// Here you can add extra code
<h1>Code rendered by wapper</h1>
<WrappedComponent {...this.props} />;
</div>
}
}
}
And you use it like this
import wrapper from './wrapper';
import Child from './Child';
const HigherWrapper = wrapper(Child);
const rootElement = document.getElementById("root");
ReactDOM.render(<HigherWrapper />, rootElement);

React redirect on click of svg element

I have a single page React App that is d3 and SVG heavy, and I would like to be able to redirect from one page to another when a user clicks on an svg rect on one of my pages. I am familiar with this.props.history.push() as well as the <Link> component from the react-router-dom library, however neither of these seem to help in this instance.
The svg element of relevance here is deep in a graphing component of mine that is 3-4 children down from the front-end's main App.js file that does all of the routing, and when I run console.log(this.props) in my component with the svg, there is no history object on the props. I'm not sure if a reproducible example is needed here, as I just need direction.
In short, I have no idea what should go into the on-click function that is associated with my svg rect, to enable redirect in my app. Any thoughts on this would be greatly appreciated!
Edit: obviously this is wrong but i tried to return a Redirect component in on-click handler and it didn't work:
...
...
function handleMouseClick() {
console.log('clicked')
return <Redirect to='/stats' />;
}
myRect.on('click', handleMouseClick)
...
Edit2: should i put the rect elements inside of components in the svg? is that even possible?
You can add the history prop from react-router to a component by wrapping it with withRouter. Just make sure whatever is mounting your component is using the wrapped version (usually by only exporting the wrapped component).
import React from 'react';
import { withRouter } from 'react-router';
class MyComponent extends React.Component {
render() {
return (
<button onClick={() => this.props.history.push('/newpage')}>
Click me
</button>
);
}
}
export default withRouter(MyComponent);

Cant import/export React components in visual studio

I'm trying something that I thought would be very basic but for some reason its just not working at all!
I'm simply trying to create 2 simple react components in 2 different jsx files and import one of them to the parent file and then use and render the child component in the parent one.
I have created a simple mvc site that simply goes to the index page that imports the selected jsx file which the first component is in. Reactjs is installed via nuget package manager. I'm still learning reactjs so I'm probably doing something glaringly wrong for this to not work.
I have tried using requires and es6 import/export but neither seem to work for me.
specifically using the import/export methods throws a syntax error even though I have both node.js and typescript installed in visual studio!
Any help would be great.
Please see code below:
Component1.jsx:
import Component2 from "./Component2.jsx"
class Component1 extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>
<div>hello</div>
</div>
);
}
}
ReactDOM.render(
<Component1 />,
document.getElementById('test')
);
Component2.jsx:
class Component2 extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div>test</div>
);
}
}
export default Component2;

using css-module with react?

The React:
/**
* Created by pingfengafei on 16/11/28.
*/
import React from 'react';
import HeaderContainer from './HeaderContainer';
import NavContainer from './NavContainer';
import ContentContainer from './ContentContainer';
import CSSModules from 'react-css-modules';
import styles from './HomePageContainer.less';
class HomePageContainer extends React.Component {
constructor(props) {
super(props);
}
render() {
return (
<div className="home-page-wrap-normal" styleName='home-page-wrap'>
<HeaderContainer />
<NavContainer />
<ContentContainer>
{this.props.children}
</ContentContainer>
</div>
);
}
}
export default CSSModules(HomePageContainer, styles, {allowMultiple: true});
The doom node :
The css style:
The webpack.config:
{
test: /\.(le|c)ss$/,
loader: "style!css?sourceMap&modules&importLoaders=1&localIdentName=[name]-[local]-[hash:base64:5]!postcss!less"
}
I want to add css modules into my React project just like
instagram with react-css-modules.
But find 2 problems:
1: Can I partly using css-module?
The child nodes of HomePageContainer-home-page-wrap-Ql_jW all lose css style, and the same with home-page-wrap-normal.
It seems that I should replace the className with sytleName in the whole project. Is there any way that I can chose where use styleName and className with both showing the correct css style.
2:Can I open sourceMap in develop model?
The class with base64 is unreadable, I need a sourceMap connecting original class name with compiled class name.
To answer your first question, you can use :global inside your css/less file in order to load the style as normal css.
Please see this:
CSS Modules - exclude class from being transformed
To answer your second question, your class name in source map should be readable enough. You can change the following to make it even more readable:
localIdentName=[name]___[local]___[hash:base64:4]

Resources