Skip to content

Instantly share code, notes, and snippets.

@kozo002
Last active April 21, 2017 01:18
Show Gist options
  • Save kozo002/e4c42c7766c45cc6a9fea1fd54361f73 to your computer and use it in GitHub Desktop.
Save kozo002/e4c42c7766c45cc6a9fea1fd54361f73 to your computer and use it in GitHub Desktop.
import React, { createElement } from "react";
import { render } from "react-dom";
import { Provider, connect } from "react-redux";
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import createLogger from "redux-logger";
import camelCase from "lodash/camelCase";
import parseJSON from "./parse-json";
/**
* this function expects like a below component
*
* class Sample extends React.Component {
* static get componentName() {
* return "Sample";
* }
* }
*
* and expects like a below html
*
* <span
* data-component="Sample"
* data-some-prop-1="hoge"
* data-some-prop-2="fuga"
* ></span>
*
* extract props from data-xxx
*
* {
* someProp1: "hoge",
* someProp2: "fuga",
* }
*/
export default function mountComponent(component) {
const mountNodes = getMountNodes(component);
mountNodes.forEach((mountNode) => {
const props = getProps(mountNode);
render(createElement(component, props), mountNode);
});
}
export function mountComponentWithRedux(component, reducers) {
const mountNodes = getMountNodes(component);
mountNodes.forEach((mountNode) => {
const props = getProps(mountNode);
const connectedComponent = connect((state) => state)(component);
const middlewares = applyMiddleware(...getReduxMiddlewares());
const store = createStore(reducers, props, middlewares);
render (
<Provider store={store}>
{createElement(connectedComponent)}
</Provider>
, mountNode);
});
}
function getMountNodes(component) {
const selector = `[data-component="${component.componentName}"]`;
return [].slice.call(document.querySelectorAll(selector));
}
function getProps(node) {
let props = {};
[].forEach.call(node.attributes, (attr) => {
const { name, value } = attr;
if (/^data\-(?!component)/.test(name)) {
const propName = camelCase(name.replace(/^data\-/, ""));
props[propName] = parseJSON(value);
}
});
return props;
}
function getReduxMiddlewares() {
let middlewareList = [thunk];
// it's needs replacing environment string tool that like envify
if (process.env.NODE_ENV !== "production") {
middlewareList.push(createLogger());
}
return middlewareList;
}
export default function parseJSON(string) {
try {
return JSON.parse(string);
} catch (e) {
return string;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment