Skip to content

Commit a65992e

Browse files
committed
Move LiveProvider to a functional component with hooks
1 parent 2cf946e commit a65992e

File tree

3 files changed

+69
-85
lines changed

3 files changed

+69
-85
lines changed

src/components/Editor/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { theme as liveTheme } from '../../constants/theme';
77
class CodeEditor extends Component {
88
static propTypes = {
99
code: PropTypes.string,
10-
disabled: PropTypes.boolean,
10+
disabled: PropTypes.bool,
1111
language: PropTypes.string,
1212
onChange: PropTypes.func,
1313
style: PropTypes.object,
Lines changed: 65 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,89 @@
1-
import React, { Component } from 'react';
1+
import React, { useEffect, useState } from 'react';
22
import PropTypes from 'prop-types';
33

44
import LiveContext from './LiveContext';
55
import { generateElement, renderElementAsync } from '../../utils/transpile';
66

7-
export default class LiveProvider extends Component {
8-
static defaultProps = {
9-
code: '',
10-
noInline: false,
11-
language: 'jsx',
12-
disabled: false
13-
};
7+
function LiveProvider({
8+
children,
9+
code,
10+
language,
11+
theme,
12+
disabled,
13+
scope,
14+
transformCode,
15+
noInline = false
16+
}) {
17+
const [state, setState] = useState({
18+
error: undefined,
19+
element: undefined
20+
});
1421

15-
static propTypes = {
16-
children: PropTypes.children,
17-
code: PropTypes.string,
18-
disabled: PropTypes.bool,
19-
language: PropTypes.string,
20-
noInline: PropTypes.bool,
21-
scope: PropTypes.object,
22-
theme: PropTypes.object,
23-
transformCode: PropTypes.node
24-
};
25-
26-
state = { unsafeWrapperError: undefined, error: undefined, element: React.Fragment }
27-
28-
componentDidMount() {
29-
const { code, scope, transformCode, noInline } = this.props;
30-
31-
this.transpile({ code, scope, transformCode, noInline });
32-
}
33-
34-
componentDidUpdate({
35-
code: prevCode,
36-
scope: prevScope,
37-
noInline: prevNoInline,
38-
transformCode: prevTransformCode
39-
}) {
40-
const { code, scope, noInline, transformCode } = this.props;
41-
if (
42-
code !== prevCode ||
43-
scope !== prevScope ||
44-
noInline !== prevNoInline ||
45-
transformCode !== prevTransformCode
46-
) {
47-
this.transpile({ code, scope, transformCode, noInline });
48-
}
49-
}
50-
51-
onChange = code => {
52-
const { scope, transformCode, noInline } = this.props;
53-
this.transpile({ code, scope, transformCode, noInline });
54-
};
55-
56-
onError = error => {
57-
this.setState({ error: error.toString() });
58-
};
59-
60-
transpile = ({ code, scope, transformCode, noInline = false }) => {
22+
function transpile(newCode) {
6123
// Transpilation arguments
6224
const input = {
63-
code: transformCode ? transformCode(code) : code,
25+
code: transformCode ? transformCode(newCode) : newCode,
6426
scope
6527
};
6628

67-
// State reset object
68-
const state = { unsafeWrapperError: undefined, error: undefined };
29+
const errorCallback = error =>
30+
setState({ error: error.toString(), element: undefined });
6931

70-
const errorCallback = err =>
71-
this.setState({ element: undefined, error: err.toString() });
72-
const renderElement = element => this.setState({ ...state, element });
32+
const renderElement = element => setState({ error: undefined, element });
7333

7434
try {
7535
if (noInline) {
76-
this.setState({ ...state, element: null }); // Reset output for async (no inline) evaluation
36+
setState({ error: undefined, element: null }); // Reset output for async (no inline) evaluation
7737
renderElementAsync(input, renderElement, errorCallback);
7838
} else {
7939
renderElement(generateElement(input, errorCallback));
8040
}
8141
} catch (error) {
82-
this.setState({ ...state, error: error.toString() });
42+
errorCallback(error);
8343
}
84-
};
44+
}
8545

86-
render() {
87-
const { children, code, language, theme, disabled } = this.props;
46+
useEffect(() => {
47+
transpile(code);
48+
}, [code, scope, noInline, transformCode]);
8849

89-
return (
90-
<LiveContext.Provider
91-
value={{
92-
...this.state,
93-
code,
94-
language,
95-
theme,
96-
disabled,
97-
onError: this.onError,
98-
onChange: this.onChange
99-
}}
100-
>
101-
{children}
102-
</LiveContext.Provider>
103-
);
104-
}
50+
const onChange = newCode => transpile(newCode);
51+
52+
const onError = error => setState({ error: error.toString() });
53+
54+
return (
55+
<LiveContext.Provider
56+
value={{
57+
...state,
58+
code,
59+
language,
60+
theme,
61+
disabled,
62+
onError,
63+
onChange
64+
}}
65+
>
66+
{children}
67+
</LiveContext.Provider>
68+
);
10569
}
70+
71+
LiveProvider.propTypes = {
72+
children: PropTypes.node,
73+
code: PropTypes.string,
74+
disabled: PropTypes.bool,
75+
language: PropTypes.string,
76+
noInline: PropTypes.bool,
77+
scope: PropTypes.object,
78+
theme: PropTypes.object,
79+
transformCode: PropTypes.func
80+
};
81+
82+
LiveProvider.defaultProps = {
83+
code: '',
84+
noInline: false,
85+
language: 'jsx',
86+
disabled: false
87+
};
88+
89+
export default LiveProvider;

stories/Live.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,9 @@ function LikeButton() {
6262
6363
return (
6464
<>
65-
<p class="likes">{likes} likes</p>
65+
<p className="likes">{likes} likes</p>
6666
<button
67-
class="button"
67+
className="button"
6868
onClick={() => increaseLikes(likes + 1)} />
6969
</>
7070
)
@@ -139,7 +139,7 @@ const TestComponent = ({ live }) => {
139139
return (
140140
<Container>
141141
<StyledEditor />
142-
<Result />
142+
{Result && <Result />}
143143
<pre>{live.error}</pre>
144144
</Container>
145145
);

0 commit comments

Comments
 (0)