Complete react newb here. I am having a really stupid issue trying to use components. When i have the components in the index.js (entry file) it works fine with import. however when i try to reference it from another component it ONLY tries to resolve the path from the parent component.
Root
- Example/Example.js
- Test/Test.js
/* In Test.js */
var Test= React.createClass({
render() {
return <div>
"Hello"
</div>
}
});
export default Test;
/* In Example.js */
import Test from './Test/Test';
var Example = React.createClass({
render() {
return <div>
<Test />
</div>
}
});
export default Example;
Now i get error:
Cannot resolve module './Test/Test' in G:\app\root\example <--- here it only looks in the root.
I think its a webpack issue? I have tried the docs and suggestions for adding resolve.root but that didnt seem to help. Being a newb I am not sure if the issue is react or webpack or where to fix it.
Your path to Test is incorrect. It should be ../Test/Test
Related
I've created an onClick handler in a very simple React function component:
export default function MyButton() {
return (
<button
onClick={() => {
console.log('test');
}}
>
Button
</button>
);
}
Now the weird part: no matter what browser I use, the event is not firing. I've created such a component hundreds of times and everything was good, until now.
For everyone else this code works, as it was intended.
I cannot share the whole project or an example repository. It's really nothing but a simple React app you see everywhere.
What could be the reason for why it's not working on my system?
EDIT:
The error was somehow within yarn. I called webpack-dev-server -d source-map --mode=development for development and I am using "webpack-dev-server": "^4.0.0-beta.0". I think the cache could've gotten corrupted somehow.
To fix it, I removed my output directory and started the script with npm instead of yarn. This way it worked, even when I use yarn again.
I really don't know why this happened. Would be happy to know why.
I also faced the same issue and the reason of the issue (in my case , probably yours ) is HtmlWebpackPlugin, HtmlWebpack Plugin is adding a addition script tag of bundle in head tag of index.html.
my html
<html>
<head>
<title>my-react-app</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
htmlwebpackplugin generated html
<html>
<head>
<title>my-react-app</title>
<script defer src="bundle.js"></script></head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>
because of this additional script tag, there was a problem in react (i read a post on reddit regarding to this problem and he also have multiple script of same bundle and he was having the same problem), i solved it by deleting my script tag, but we can use copywebpack plugin to just copy html. Or other solution is to configure htmlwebpackplugin suck a way that it will not inject any addition tags
...
new HtmlWebpackPlugin({
name: "index.html",
inject: false,
template: path.resolve(__dirname, "public/index.html"),
}),
...
Use named function instead of anonymous function. Named functions are very useful for identifying what functions caused errors during development as well as when retrieving logs from your users.
import React from "react";
export default function MyButton() {
const handleChange = () => {
console.log("test");
};
return <button onClick={handleChange}>Button</button>;
}
It is a good practice to name-all-functions for a better developer debugging (and development) experience which anonymous function does not provide.
For more clarification between Named and Anonymous function Learn the benefits of Named vs Anonymous function here
Try typing your function as React.FC.
Create a typescript (tsx) file and use the upcoming code:
import React from "react";
export const MyButton: React.FC = () => {
return (
<button
onClick={() => {
console.log("test");
}}
>
Button
</button>
);
};
Note that using this code, you are typing the component making sure that your function is typed as React.FunctionComponent.
Did you import this in your file, if not then add this tine on top
import React from 'react';
I can't run opencv.js and react.js together because (I think) opencv.js is too big (7.8mb) for yarn to compile (I get max callstack error). Given that, I also can't load opencv.js in the index.html because it loads too slowly for React to pick it up, giving me cv is not defined.
Creating an onLoad="myfunc()" function gets me furthest, as I can set a var loaded to be true and wrap an if statement around the ReactDOMrender. But it doesn't ever pick up when the var changes to true and never renders.
I've tried the following:
Importing the opencv.js script right into my index.js where I'm testing this out. I get a Max callstack error. I'm guessing this is because opencv.js is around 8mb and the compiler doesn't like it?
I've tried to add opencv.js in the public/index.html file. I load it using async and add /*global cv*/ to the top of my index.js file. I get the error cv is not defined.
import React from 'react';
/*global cv*/
var mytest = function() {
var test = cv.Mat();
console.log(test + ' if you see something before this, opencv loaded');
}
mytest();
function App() {
return (
<div>hello world</div>
)}
export default App;
and in the of the index.html:
<script async src="opencv.js" type="text/javascript"></script>
This fails and says cv is not defined. I've also tried this with an onLoad="whenOpenCvLoads()" using this function to set a var to be true, and wrapping (what I believe to be) the first called function in react like this:
if(openCvIsReady === true){
ReactDOM.render(<App />, document.getElementById('root'));
console.log(openCvIsReady + ' in react');
}
This evaluates to false and never runs when the variable eventually becomes true.
I have been trying to setup webpack, babel, and npm to work with react. I followed the guide on codeacademy - https://www.codecademy.com/articles/react-setup-v. On their last step, they say to create an App.js. Now App.js is a js file, therefore no JSX synthax can be written. This is how my App.js looks:
var React = require('react');
var Component = React.createClass({
render: function (){
return(
<p>Hello World</p>
)
}
});
module.exports = Component;
Now, I know why it throws me an error of unexpected token at line 5 of the code. JS does not recognize the paragraph tag. I tried converting the file to jsx, but that way I cannot import it in my index.js file. I have been trying to setup react for days, and it is very frustrating because I just want to start coding with React very soon.
I'm trying to introduce React with ES6 into my app, which is built with Gulp. I can get React working alone, and ES6 working alone. But trying to import crashes my Gulp build. Gulp's error is:
Line 14: Illegal import declaration
My HTML page includes React and the built JS file:
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.12.2/react.min.js"></script>
<script src="js/app.js"></script>
app.js looks like this:
import {Child} from './child.js';
var Parent = React.createClass({
render: function(){
const y = 3; //es6 works
return (
<div>
<div> This is the parent {y}. </div>
<Child name="child"/>
</div>
)
}
});
React.render(<Parent />, document.getElementById('container'));
child.js is in the same directory and looks like this:
var Child = React.createClass({
render: function(){
return (
<div>
and this is the <b>{this.props.name}</b>.
</div>
)
}
});
export default Child;
The part of my Gulp file that compiles ES6 with Babel:
gulp.task('babel', function(){
gulp.src('js/app.js')
.pipe(react())
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest('dist/js'));
});
What am I missing/doing wrong that is preventing me from using import?
You have to apply the es6module option to gulp-react to allow for importing of modules:
.pipe(react({
es6module: true
}))
Then, fix your import statement. Since Child is exported as default, import it like this:
import Child from './child.js';
Note: gulp-react was deprecated in favor of gulp-babel so I suggest using that instead if you're already using it for es2015. use gulp-babel instead and install the react preset for Babel:
npm install --save-dev babel-preset-react
Finally, apply it to gulp-babel:
presets: ['es2015', 'react']
Try
import Child from './child';
I'm very loosely following the example here up until the point where it starts running the dev server.
I have a test React component (in scripts/test.jsx):
/** #jsx React.DOM */
var React = require('react');
var Test = React.createClass({
render: function(){
return <h1>HI!</h1>
}
});
module.exports = Test;
I have a webpack.config where I'm using the jsx loader against the source directory (It's basically the same as the one in the example except I'm adding the library properties).
I run webpack and it generates the bundle file like I expect, however, when I try to use the component in an html file (after including the bundle.js script reference) I get the following in console: "Uncaught ReferenceError: Test is not defined".
The HTML contains the following:
<div id="hi">
</div>
<script type="text/jsx">
/** #jsx React.DOM */
React.renderComponent(
<Test />,
document.getElementById('hi')
);
</script>
Am I doing something incorrect to use a component that is defined in CommonJS style against an html page that isn't technically using a module loader (I'm trying to treat this test as if it's someone who is trying to load the component without any type of structured module loader)?
The output of the webpack is available here
EDIT 2: The full example code is available as a github repo
Yeah, you'd be better off following the example and requiring Test from a .jsx file rather than inlining it in the HTML.
Otherwise, Test needs to be exported as a global, so you'd need to follow similar conventions to the browserify --standalone flag, which looks to be something like this:
output: {
library: "Test",
libraryTarget: "umd"
}
http://webpack.github.io/docs/webpack-for-browserify-users.html#standalone
Edit: After looking at your GH repo, you have:
<script src="bundle.js" type="text/js"></script>
instead of
<script src="bundle.js" type="text/javascript"></script>
so it wasn't loading bundle at all. Further, you can't have 2 separate copies of react, the way you have it currently you're requiring React from within webpack, and then you're also loading it on the page. You should either export a function which takes the React object, or use the global to be able to use it outside of the bundle.
For example this would work:
/** #jsx React.DOM */
module.exports = function(React) {
var Test = React.createClass({
render: function(){
return <h1>HI!!</h1>
}
});
return Test;
};
and then:
/** #jsx React.DOM */
React.renderComponent(
Test(React)(),
document.getElementById('hi')
);
or this
/** #jsx React.DOM */
var Test = React.createClass({
render: function(){
return <h1>HI!!</h1>
}
});
module.exports = Test;
and then:
/** #jsx React.DOM */
React.renderComponent(
<Test />,
document.getElementById('hi')
);
Though I can't imagine most folks consuming a React package are going to be loading it with a script tag, and you generally don't want globals, so it's probably best to just use the CommonJS style require and let people figure out shimming or whatever.