Skip to content

React hooks wip #457

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

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .ruby-version

This file was deleted.

6 changes: 3 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
source "https://rubygems.org"
ruby "2.4.1"
ruby "2.6.1"

gem "react_on_rails", "11.0.7"
gem "webpacker"
Expand Down Expand Up @@ -94,13 +94,13 @@ end
group :test do
gem "capybara", "2.18.0"
gem "capybara-screenshot"
gem "capybara-webkit"
# gem "capybara-webkit"
gem "chromedriver-helper"
gem "coveralls", require: false
gem "database_cleaner"
gem "generator_spec"
gem "launchy"
gem "poltergeist"
# gem "poltergeist"
gem "rails_best_practices"
gem "rspec-rails", "3.7.2"
gem "selenium-webdriver"
Expand Down
20 changes: 5 additions & 15 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -70,15 +70,11 @@ GEM
capybara-screenshot (1.0.21)
capybara (>= 1.0, < 4)
launchy
capybara-webkit (1.15.0)
capybara (>= 2.3, < 4.0)
json
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
chromedriver-helper (1.2.0)
archive-zip (~> 0.10)
nokogiri (~> 1.8)
cliver (0.3.2)
code_analyzer (0.4.8)
sexp_processor
coderay (1.1.2)
Expand Down Expand Up @@ -128,7 +124,7 @@ GEM
json (2.1.0)
launchy (2.4.3)
addressable (~> 2.3)
libv8 (6.3.292.48.1)
libv8 (6.7.288.46.1)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
Expand All @@ -144,8 +140,8 @@ GEM
mimemagic (0.3.2)
mini_mime (1.0.0)
mini_portile2 (2.3.0)
mini_racer (0.1.15)
libv8 (~> 6.3)
mini_racer (0.2.4)
libv8 (>= 6.3)
minitest (5.11.3)
multi_json (1.13.1)
nio4r (2.3.1)
Expand All @@ -155,10 +151,6 @@ GEM
parser (2.5.1.0)
ast (~> 2.4.0)
pg (1.0.0)
poltergeist (1.18.0)
capybara (>= 2.1, < 4)
cliver (~> 0.3.1)
websocket-driver (>= 0.2.0)
powerpack (0.1.1)
pry (0.11.3)
coderay (~> 1.1.0)
Expand Down Expand Up @@ -334,7 +326,6 @@ DEPENDENCIES
bundler-audit
capybara (= 2.18.0)
capybara-screenshot
capybara-webkit
chromedriver-helper
coffee-rails
coveralls
Expand All @@ -347,7 +338,6 @@ DEPENDENCIES
listen
mini_racer
pg
poltergeist
pry
pry-byebug
pry-doc
Expand Down Expand Up @@ -375,7 +365,7 @@ DEPENDENCIES
webpacker

RUBY VERSION
ruby 2.4.1p111
ruby 2.6.1p33

BUNDLED WITH
1.16.0
1.17.3
1 change: 1 addition & 0 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ def no_router
end

def simple; end
def simple_hooks; end

private

Expand Down
13 changes: 13 additions & 0 deletions app/views/pages/simple_hooks.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<h2>Using React (with Hooks) + Rails Backend (with
<a href="https://github.com/shakacode/react_on_rails">react_on_rails gem</a>)</h2>
<p>This example is much simpler than the one using React + Redux and is appropriate when:</p>
<ul>
<li>No or minimal MVC</li>
<li>No async necessary</li>
<li>No server rendering</li>
<li>No pre-population of props</li>
</ul>
<hr/>

<!-- This component is super simple! So no redux, no prerendering. -->
<%= react_component('SimpleHooksCommentScreen', props: {}, prerender: false) %>
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,16 @@ const NavigationBar = (props) => {
<div className="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul className="nav navbar-nav">
<li className={classNames(
{ active: (pathname === paths.ROUTER_PATH || pathname === paths.REACT_ROUTER_PATH) },
)}>
{ active: (pathname === paths.ROUTER_PATH || pathname === paths.REACT_ROUTER_PATH) },
)}>
<a href={paths.ROUTER_PATH}>React Router Demo</a>
</li>
<li className={classNames({ active: (pathname === paths.NO_ROUTER_PATH) })}>
<a href={paths.NO_ROUTER_PATH}>React Demo</a>
</li>
<li className={classNames({ active: (pathname === paths.SIMPLE_HOOKS_REACT_PATH) })}>
<a href={paths.SIMPLE_HOOKS_REACT_PATH}>Simple Hooks React</a>
</li>
<li className={classNames({ active: (pathname === paths.SIMPLE_REACT_PATH) })}>
<a href={paths.SIMPLE_REACT_PATH}>Simple React</a>
</li>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class SimpleCommentScreen extends BaseComponent {
<h2>
{formatMessage(defaultMessages.comments)}
</h2>
{ SelectLanguage(handleSetLocale, locale) }
{SelectLanguage(handleSetLocale, locale)}
<ul>
<li>{formatMessage(defaultMessages.descriptionSupportMarkdown)}</li>
<li>{formatMessage(defaultMessages.descriptionDeleteRule)}</li>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

class ErrorBoundary extends React.PureComponent {
constructor(props) {
super(props);
this.state = { hasError: false };
}

static getDerivedStateFromError(error) {
// Update state so the next render will show the fallback UI.
console.log(error, "getDerivedStateFromError");
return { hasError: true };
}

componentDidCatch(error, info) {
// You can also log the error to an error reporting service
console.log("xxxxxxxxxxxx")
console.log(error, info);
console.log("xxxxxxxxxxxx")
}

render() {
if (this.state.hasError) {
// You can render any custom fallback UI
return <h1>Something went wrong.</h1>;
}

return this.props.children;
}
}

export default ErrorBoundary;
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { React, useState, useEffect } from "react";
import request from "axios";
import Immutable from "immutable";
import _ from "lodash";
// import ReactOnRails from "react-on-rails";
// import { IntlProvider, injectIntl } from "react-intl";
// import BaseComponent from 'libs/components/BaseComponent';
// import SelectLanguage from "libs/i18n/selectLanguage";
// import { defaultMessages, defaultLocale } from "libs/i18n/default";
// import { translations } from "libs/i18n/translations";

// import CommentForm from "../CommentBox/CommentForm/CommentForm";
// import CommentList from "../CommentBox/CommentList/CommentList";

import ReactOnRails from "react-on-rails";
import BaseComponent from 'libs/components/BaseComponent';
import SelectLanguage from "libs/i18n/selectLanguage";
import { defaultMessages, defaultLocale } from "libs/i18n/default";
import { translations } from "libs/i18n/translations";

import CommentList from "../CommentBox/CommentList/CommentList";
import css from "../SimpleCommentScreen/SimpleCommentScreen.scss";

import ErrorBoundary from "./ErrorBoundary"

function SimpleHooksCommentScreen() {
const [comments, setComments] = useState(Immutable.fromJS([]));
const [isSaving, setIsSaving] = useState(false);
const [fetchCommentsError, setFetchCommentsError] = useState(null);
const [submitCommentError, setSubmitCommentError] = useState(null);

useEffect(() => {
this.fetchComments();
});

function fetchComments() {
return request
.get("comments.json", { responseType: "json" })
.then(res =>
setComments(Immutable.fromJS(res.data.comments))
)
.catch(error => setFetchCommentsError(error));
}

function handleCommentSubmit(comment) {
setIsSaving(true);

const requestConfig = {
responseType: "json",
headers: ReactOnRails.authenticityHeaders()
};

return request
.post("comments.json", { comment }, requestConfig)
.then(() => {
const $$comment = Immutable.fromJS(comment);
setComments(comments.unshift($$comment));
setSubmitCommentError(null);
setIsSaving(false);
})
.catch(error => {
setSubmitCommentError(error)
setIsSaving(false);
});
}


const { handleSetLocale, locale, intl } = this.props;
const { formatMessage } = intl;
const cssTransitionGroupClassNames = {
enter: css.elementEnter,
enterActive: css.elementEnterActive,
leave: css.elementLeave,
leaveActive: css.elementLeaveActive
};

return (
<div className="commentBox container">
<h2>{formatMessage(defaultMessages.comments)}</h2>
{SelectLanguage(handleSetLocale, locale)}
<ul>
<li>{formatMessage(defaultMessages.descriptionSupportMarkdown)}</li>
<li>{formatMessage(defaultMessages.descriptionDeleteRule)}</li>
<li>{formatMessage(defaultMessages.descriptionSubmitRule)}</li>
</ul>
<CommentForm
isSaving={isSaving}
actions={{ submitComment: handleCommentSubmit }}
error={submitCommentError}
cssTransitionGroupClassNames={cssTransitionGroupClassNames}
/>
<CommentList
$$comments={comments}
error={fetchCommentsError}
cssTransitionGroupClassNames={cssTransitionGroupClassNames}
/>
</div>
);
}

export default SimpleHooksCommentScreen;

class I18nWrapper extends BaseComponent {
constructor(props) {
super(props);

this.state = {
locale: defaultLocale
};

_.bindAll(this, "handleSetLocale");
}

handleSetLocale(locale) {
this.setState({ locale });
}

componentDidCatch(error, info) {
debugger;
console.log("xxxxxxxxxxxx")
console.log(error, info);
console.log("xxxxxxxxxxxx")
}

render() {
console.log("xxxxxxxxxxxx Render()")
console.log(this.state, this.props);
console.log("xxxxxxxxxxxx")

const { locale } = this.state;
const messages = translations[locale];
// const InjectedSimpleHooksCommentScreen = injectIntl(SimpleHooksCommentScreen);

// return (
// <IntlProvider locale={locale} key={locale} messages={messages}>
// <InjectedSimpleHooksCommentScreen
// {...this.props}
// locale={locale}
// handleSetLocale={this.handleSetLocale}
// />
// </IntlProvider>
// );

return (
<ErrorBoundary>
<SimpleHooksCommentScreen
{...this.props}
locale={locale}
handleSetLocale={this.handleSetLocale}
/>
</ErrorBoundary>
);
}
}
1 change: 1 addition & 0 deletions client/app/bundles/comments/constants/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,5 @@ export const ROUTER_PATH = '/';
export const REACT_ROUTER_PATH = '/react-router';
export const NO_ROUTER_PATH = '/no-router';
export const SIMPLE_REACT_PATH = '/simple';
export const SIMPLE_HOOKS_REACT_PATH = '/simple-hooks';
export const RAILS_PATH = '/comments';
2 changes: 2 additions & 0 deletions client/app/bundles/comments/startup/clientRegistration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import zh from 'react-intl/locale-data/zh';
import App from './App';
import RouterApp from './ClientRouterApp';
import SimpleCommentScreen from '../components/SimpleCommentScreen/SimpleCommentScreen';
import SimpleHooksCommentScreen from '../components/SimpleHooksCommentScreen/SimpleHooksCommentScreen';
import routerCommentsStore from '../store/routerCommentsStore';
import commentsStore from '../store/commentsStore';
import NavigationBarApp from './NavigationBarApp';
Expand All @@ -25,6 +26,7 @@ ReactOnRails.register({
RouterApp,
NavigationBarApp,
SimpleCommentScreen,
SimpleHooksCommentScreen,
});

ReactOnRails.registerStore({
Expand Down
2 changes: 2 additions & 0 deletions client/app/bundles/comments/startup/serverRegistration.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ReactOnRails from 'react-on-rails';
import App from './App';
import RouterApp from './ServerRouterApp';
import SimpleCommentScreen from '../components/SimpleCommentScreen/SimpleCommentScreen';
import SimpleHooksCommentScreen from '../components/SimpleHooksCommentScreen/SimpleHooksCommentScreen';
import NavigationBarApp from './NavigationBarApp';
import routerCommentsStore from '../store/routerCommentsStore';
import commentsStore from '../store/commentsStore';
Expand All @@ -14,6 +15,7 @@ ReactOnRails.register(
RouterApp,
NavigationBarApp,
SimpleCommentScreen,
SimpleHooksCommentScreen,
},
);

Expand Down
8 changes: 4 additions & 4 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,14 +73,14 @@
"loader-utils": "^1.1.0",
"lodash": "^4.17.4",
"marked": "^0.3.6",
"node-sass": "^4.7.2",
"node-sass": "^4.11.0",
"node-uuid": "^1.4.8",
"postcss-loader": "^2.0.8",
"prop-types": "^15.6.0",
"react": "^16.1.1",
"react": "^16.8.4",
"react-addons-css-transition-group": "^15.6.2",
"react-bootstrap": "^0.31.5",
"react-dom": "^16.1.1",
"react-dom": "^16.8.4",
"react-intl": "^2.4.0",
"react-on-rails": "11.0.7",
"react-redux": "^5.0.6",
Expand Down Expand Up @@ -132,4 +132,4 @@
"^.+\\.jsx?$": "babel-jest"
}
}
}
}
Loading