Getting problems implementing react-select package - reactjs

I am working in a react app that is a form that contains a few dropdown components (from MS fabric).
I got a request asking for change some of these dropdown to combobox and the MS fabric combobox package doesn't work very well so I looked the internet and I found a package called React-select.
I tested the package in a simple react app before implementing it in the real project and it worked very well.
The problem is when I try to implement the same package in the real project. The problem is that as soon I implement the component my app stop working. If I remove the line the app works again.
The major difference between the test app and the real project is that in the project I am using Typescript. I have also other components in the project and just for testing I removed all of them but the problem remain.
No error messages in the developer console nor in the react app itself.
My implementation is like this:
Import the module:
import Select from "react-select";
Inside componentDidUpdate:
componentDidUpdate(prevProps: ISearchPersonFormProps): void {
if (this.props != prevProps) {
let civilServants = [] as any;
this.props.civilServants.forEach(civilServant => {
civilServants.push({ label: civilServant.PKATBESKR, value: civilServant.Id })
})
this.setState(
{
civilServants: civilServants
});
}
In my ISearchPersonFormProps I have this interface:
civilServants: ICivilServant[];
And in the render method i use the like this:
<Select options={this.state.civilServants} />
The civilServants state is of type IDropdownOptions[].
I tested the state of civilServants just before the Select-line and it contains all the information that I want to use in the Select component.
When I remove this Select-line the app works again otherwise nothing shows on the screen and no error message shows in the dev console.
Some info of my app:
React version: 16.11.10
Typescript version: 3.7.2
React-select version: 3.0.8
#types/react-select version: 3.0.8
Any comment will be helpful,
Thanks!
UPDATE:
this is the code for the component:
import * as React from "react";
import {
TextField,
Dropdown,
IDropdownOption,
Checkbox,
PrimaryButton,
Stack,
Label
} from "office-ui-fabric-react";
import { ISearchPersonFormProps } from "./ISearchPersonFormProps";
import { ISearchPersonFormState } from "./ISearchPersonFormState";
import Select from "react-select";
export class SearchPersonForm extends React.Component<
ISearchPersonFormProps,
ISearchPersonFormState
> {
constructor(props: ISearchPersonFormProps) {
super(props);
this.state = {
civilServants: [],
selectedOption: null
};
this._handleChange = this._handleChange.bind(this);
}
componentDidUpdate(prevProps: ISearchPersonFormProps): void {
if (this.props != prevProps) {
let civilServants: any[] = [];
this.props.civilServants.forEach(civilServant => {
civilServants.push({
value: civilServant.Id,
label: civilServant.PKATBESKR
});
});
this.setState({
civilServants: civilServants
});
}
}
private _handleChange = (selectedOption: any) => {
this.setState(
{
selectedOption
},
() => console.log(this.state.selectedOption)
);
};
public render(): React.ReactElement<ISearchPersonFormProps> {
const { selectedOption } = this.state;
console.log(this.state.civilServants);
return (
<div className="search-form">
<Stack horizontalAlign="start" tokens={{ childrenGap: 20 }}>
<Stack horizontal tokens={{ childrenGap: 25 }}>
<Select
value={selectedOption}
onChange={this._handleChange}
options={this.state.civilServants}
/>
</Stack>
</Stack>
</div>
);
}
}
This is the code for the porp interface:
import { ICivilServant } from "./ICivilServant";
export interface ISearchPersonFormProps {
civilServants: ICivilServant[];
}
This is the code for the state interface:
export interface ISearchPersonFormState {
selectedOption: any;
civilServants: any;
}
The ICivilServant is the interface that is used when the data is fetched from the DB.
The console log in the component shows that the data from the DB is correctly fetched.
But as I said before, as soon I add the Select component the app stop working without any error message.
UPDATE 2: Package.json
{
"name": "rk-proper",
"description": "Displays forms and listings (mostly) for everything regarding the solution.",
"configurationType": "Web Part",
"cewpHtmlContent": "<div id=\"proper-webpart-container\">​</div>",
"version": "0.1.0",
"private": true,
"dependencies": {
"react": "^16.11.0",
"react-dom": "^16.11.0",
"react-scripts": "3.2.0"
},
"scripts": {
"dev": "concurrently \"webpack --config webpack.dev.js --watch\" \"gulp serve\"",
"build": "webpack --config webpack.release.js",
"build-dev": "webpack --config webpack.dev.js",
"clean": "gulp clean",
"configure-sp": "#powershell -NoProfile -ExecutionPolicy Unrestricted -Command ../StartDevelopment.ps1"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#types/react": "^16.9.11",
"#types/react-dom": "^16.9.4",
"#types/react-table": "^6.8.5",
"#types/react-tabs": "^2.3.1",
"assets-webpack-plugin": "^3.9.10",
"awesome-typescript-loader": "^5.2.1",
"concurrently": "^5.0.0",
"gulp": "^4.0.2",
"#types/sharepoint": "^2016.1.6",
"gulp-clean": "^0.4.0",
"gulp-serve": "^1.4.0",
"node-sass": "^4.13.0",
"source-map-loader": "^0.2.4",
"typescript": "^3.7.2",
"webpack-cli": "^3.3.10",
"webpack-merge": "^4.2.2",
"office-ui-fabric-react": "^7.54.0",
"react-table": "^6.10.3",
"react-tabs": "^3.0.0"
}
}

Checkout this example here. Instead of value prop they are using defaultValue. Take a look of the documentation and try to change it in your code to see if this is the problem.

Related

Using Rollup to bundle my lib using RTKQ results in the error:

The error in question is could not find react-redux context value; please ensure the component is wrapped in a <Provider>.
I first describe particulars about the library.
Afterwards I describe the environment in which it is run and the error in more detail.
The lib
The lib in question is just a collection of api calls governed by RTKQ.
The apiSlice is exported and can then be used by consumer packages to add it to their store.
I must note that this DID work in the past when the collection of API calls was just another file in the same repo, before I (tried) to move it into it's own and make a lib out of it.
It even still worked in the very early versions of the lib, when I just ... didn't bundle it at all, releasing the bare source code as a package.
It only now stopped working after I tried to do it the proper way.
Its rollup config looks like so:
const resolve = require('#rollup/plugin-node-resolve');
const commonjs = require('#rollup/plugin-commonjs');
const peerDepsExternal = require('rollup-plugin-peer-deps-external');
const babel = require('#rollup/plugin-babel');
const packageJson = require('./package.json');
module.exports = {
input: 'src/index.js',
external: [/#babel\/runtime/],
output: [
{
file: packageJson.module,
format: 'es',
sourcemap: true,
}
],
plugins: [
peerDepsExternal(),
resolve(),
babel({
exclude: 'node_modules/**',
babelHelpers: 'runtime',
}),
commonjs({
// the #rollup/plugin-babel readme insists that this should be placed before babel runs;
// but this never worked and in all examples I found this was the way it is here.
strictRequires: true,
}),
],
};
Its package.json looks like so:
{
"name": "some-name",
"version": "1.1.2",
"main": "dist/esm/index.js",
"files": [
"dist"
],
"dependencies": {
"#babel/runtime": "^7.20.6",
"#faker-js/faker": "^7.6.0",
"#reduxjs/toolkit": "^1.8.0",
"luxon": "^3.1.0",
"np": "^7.6.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-redux": "^8.0.2",
"reactjs-localstorage": "^1.0.1"
},
"scripts": {
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"prepare": "npm run co:login",
"prepublishOnly": "npm run build && np --no-publish --no-yarn --no-cleanup",
"build": "rollup --config",
"start": "webpack serve",
"devBuild": "webpack --mode=development",
"test": "echo \"No tests yet\""
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"devDependencies": {
"#babel/core": "^7.20.5",
"#babel/plugin-transform-runtime": "^7.19.6",
"#babel/preset-env": "^7.20.2",
"#rollup/plugin-babel": "^6.0.3",
"#rollup/plugin-commonjs": "^24.0.0",
"#rollup/plugin-node-resolve": "^15.0.1",
"eslint": "^8.17.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.0",
"eslint-plugin-storybook": "^0.5.12",
"rollup": "^3.7.5",
"rollup-plugin-peer-deps-external": "^2.2.4",
"webpack": "^5.70.0",
"webpack-cli": "^4.10.0",
"webpack-dev-server": "^4.11.1"
}
}
Its .babelrc file
{
"presets": ["#babel/preset-env"],
"plugins": ["#babel/plugin-transform-runtime"]
}
I exports it's api slice created with RTKQ's createApi() and also all defined endpoints.
The consumer
The current sole consumer is a component lib which uses storybook for testing.
Here is part of it's preview.js
import {
createTheme,
CssBaseline,
responsiveFontSizes,
ThemeProvider,
} from '#mui/material';
import { SnackbarProvider } from 'notistack';
import { MemoryRouter } from 'react-router';
import { Provider } from 'react-redux';
import { configureStore } from '#reduxjs/toolkit';
import { apiSlice} from '#my_company/the_lib_with_the_error'; // that's the lib
import { useDispatch } from 'react-redux';
import { useEffect } from 'react';
import { initialize as initializeMSW, mswDecorator } from 'msw-storybook-addon';
import { ConfirmProvider } from 'material-ui-confirm';
// test store
const store = configureStore({
reducer: {
[apiSlice.reducerPath]: apiSlice.reducer,
},
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(apiSlice.middleware),
devTools: { trace: true },
});
let theme = createTheme({/** long theming code */});
theme = responsiveFontSizes(theme);
initializeMSW({ waitUntilReady: false });
// I have also incorporated the suggestions of Linda Paiste's answer.
// Sadly, they had no effect.
const SetupApi = () => {
const dispatch = useDispatch();
useEffect(() => {
dispatch(timumApiSlice.util.resetApiState());
}, [dispatch]);
return null;
}
const stdLayout = (Story) => {
store.dispatch(timumApiSlice.util.resetApiState());
return (
<>
<Provider store={store}>
<ThemeProvider theme={theme}>
<SnackbarProvider
maxSnack={3}
autoHideDuration={3000}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
>
<ConfirmProvider>
<>
<CssBaseline />
<SetupApi />
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
</>
</ConfirmProvider>
</SnackbarProvider>
</ThemeProvider>
</Provider>
</>
);
};
Has anyone any ideas?
Edit 1
clarified how my setup is.
restructured the question to make it clearer.
The Provider should be outside of all dispatch calls, not in the same component. You are getting around this by using store.dispatch instead of useDispatch, but a better approach would be to move that call into a sub-component which is rendered inside of the Provider. Like this:
const SetupApi = () => {
// It's okay to use the useDispatch hook here, because this component is rendered
// inside of the Provider.
const dispatch = useDispatch();
// Move the side-effects into a useEffect
useEffect(() => {
// I'm not sure that this is really needed though? Isn't your store empty?
dispatch(timumApiSlice.util.resetApiState());
window.timumApiSlice = timumApiSlice;
}, [dispatch]);
return null;
}
const stdLayout = (Story) => {
return (
<Provider store={store}>
<ThemeProvider theme={theme}>
<SnackbarProvider
maxSnack={3}
autoHideDuration={3000}
anchorOrigin={{ horizontal: 'right', vertical: 'bottom' }}
>
<ConfirmProvider>
<CssBaseline />
<SetupApi/>
<MemoryRouter initialEntries={['/']}>
<Story />
</MemoryRouter>
</ConfirmProvider>
</SnackbarProvider>
</ThemeProvider>
</Provider>
);
};
I also moved the Redux <Provider> outside of your other providers just in case those components are using Redux data.
I can't guarantee that this alone will fix your issues because I don't fully understand your setup.
You must make sure that your store variable contains both the middleware and the reducer from your timumApiSlice API object.
I finally managed to figure it out.
First, I didn't set react-redux and #redux/redux-toolkit as peerDependencies.
Instead they were handled as normal dependencies. This led to rollup bundling them into the package.
The component lib itself declared react-redux and #redux/redux-toolkit as dependencies.
I believe that this caused the apiSlice to be created using the redux of the lib but the context was set by the redux of the component lib.
(But this is only an assumptions and may be wrong. Please correct me if so.)
Second, for basically the same reason, I did the same for react and react-dom.

Are dynamic and external React components possible in runtime?

We're developing a dashboard React-application in which other (trusted) developers can create their own React-widgets in separate environments. The goal would be a situation where new widgets wouldn't require updation to the dashboard-application and instead, these external React-components could be loaded at runtime.
So developer A would have his own project, where he would bundle a React-component into a js-file, which would be forwarded to a hosting site, S3 for example where the dashboard application could read them via a string, at runtime.
For example a weather-widget:
import React, {useState} from "react";
function Weather() {
const [city, setCity] = useState("city");
const weatherUri = `https://wttr.in/${city}_tqp0.png`;
return (
<div>
<input type="text" value={city} onChange={(e) => setCity(e.target.value)}/>
<div>
<img src={weatherUri} alt={city}/>
</div>
</div>
);
}
export default Weather;
This could be then imported to the dashboard-application. I've understood that React's dynamic code-splitting with dynamic url would work here. Either via a situation where widget would have its own React-library, or it'd get it from the dashboard-application. We've, in fact, made this to work, but as soon as we add a state to the component, it breaks:
Uncaught TypeError: Cannot read properties of null (reading 'useState')
at Object.useState (react.development.js:1612:23)
at Weather (weather_widget.js:36:33)
We've configured the widget-component's configuration as follows (React-library will be imported from the dashboard-application):
// ====== vite.config.js ========== (widget)
export default defineConfig({
plugins: [react()],
define: {
'process.env': {}
},
build: {
lib: {
entry: 'src/lib/Weather.tsx',
name: 'Weather',
fileName: 'weather',
formats: ['es']
},
rollupOptions: {
plugins: [
externalGlobals({
react: "React"
})
],
external: ['react'],
output: {
globals:{
react: 'React'
}
}
}
},
})
// ===== package.json ===== (widget)
{
"name": "weather",
"private": true,
"version": "0.0.0",
"type": "module",
"files": [
"dist"
],
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview"
},
"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0",
"rollup-plugin-external-globals": "^0.6.1"
},
"devDependencies": {
"#types/node": "18.7.23",
"#types/react": "18.0.21",
"#types/react-dom": "^18.0.6",
"#vitejs/plugin-react": "^1.0.7",
"path": "^0.12.7",
"typescript": "^4.6.4",
"vite": "^2.8.0"
}
}
This is how we've tried to import it to the dashboard-application:
export const WidgetCard = (widgetId: string) => {
const WidgetComponent = React.lazy(() =>
import(`/path/to/${widgetId}.js`));
return
<>
<Suspense fallback={<Loading/>}>
<WidgetComponent/>
</Suspense>
</>
)
});
For the final product, the logic would be as follows:
User will generate a JS-bundle of their React-component
User will call some sort of API, which will save bundle to a hosting site and also add the new widget to a database of some sort.

Invalid hook creating Liferay React component

I'm trying to create custom react components based on Liferay's Clay components.
Using e.g. just a ClayButton works, but as soon as i try to use hooks (like React.useState), the browser console tells me:
Minified React error #321; visit https://reactjs.org/docs/error-decoder.html?invariant=321 for the full message
The full message tells me i could be using mismatching versions of react and react-dom. I'm not.
I also don't have 2 different versions of react, according to the test described there.
I created a minimal example module at https://github.com/ReFl3x0r/liferay-react-component-test which can be tested in a Liferay Gradle Workspace.
There's also an older thread in Liferay Forums discussing this error, but with no solution.
(https://liferay.dev/ask/questions/development/re-lr-7-3-react-portlet-invalid-hook-call)
What am i doing wrong?
EDIT:
Trying to point out the main code snippets.
First CustomButtonFail.es.js:
import React from 'react';
import ClayButton from '#clayui/button';
const CustomButton = () => {
const [name, setName] = React.useState('test');
return (
<ClayButton displayStyle='primary'>
TEST
</ClayButton>
);
}
export default CustomButton;
The package.json:
{
"dependencies": {
"#clayui/button": "^3.40.0",
"#clayui/css": "3.x",
"react": "^16.12.0",
"react-dom": "^16.12.0"
},
"devDependencies": {
"#liferay/npm-scripts": "47.0.0",
"react-test-renderer": "^16.12.0"
},
"name": "component-test",
"scripts": {
"build": "liferay-npm-scripts build"
},
"version": "1.0.0"
}
The view.jsp including the component (shortened):
<%#taglib uri="http://liferay.com/tld/react" prefix="react" %>
<div class="react-component-failing">
<react:component
module="js/CustomButtonFail.es"
/>
</div>
I finally got it working. Reducing package.json like this:
{
"devDependencies": {
"#liferay/npm-scripts": "47.0.0"
},
"name": "component-test",
"scripts": {
"build": "liferay-npm-scripts build"
},
"version": "1.0.0"
}
and adding a ".npmbundlerrc" in modules root with content:
{
"config": {
"imports": {
"frontend-taglib-clay": {
"#clayui/button": ">=3.40.0",
"#clayui/css": ">=3.x"
},
"#liferay/frontend-js-react-web": {
"react": ">=16.12.0"
}
}
}
}
did the trick.
Working example is at https://github.com/ReFl3x0r/liferay-react-component-test/tree/working

My Uppy suddenly gives me the error this.uppy.addFiles is not a function

I'm new to this and I get this error and can't figure out why please advice:
Looks like the Error is inside Uppy something.
I follow Uppy Tutorial docs like .use(Dashboard, {... and it was working but suddenly this error I try to back track but no luck
I add files from My Device and and then error happens no breakpoint are hit anywhere what I'm a missing
Here is my simple Uppy:
import React from "react";
import "#uppy/core/dist/style.css";
import "#uppy/status-bar/dist/style.css";
import "#uppy/drag-drop/dist/style.css";
import "#uppy/progress-bar/dist/style.css";
import "#uppy/dashboard/dist/style.css";
import "./styles.css";
const Uppy = require("#uppy/core");
// const Dashboard = require("#uppy/dashboard");
const GoogleDrive = require("#uppy/google-drive");
const Dropbox = require("#uppy/dropbox");
const Instagram = require("#uppy/instagram");
const Webcam = require("#uppy/webcam");
const Tus = require("#uppy/tus");
const {
Dashboard,
DashboardModal,
DragDrop,
ProgressBar,
} = require("#uppy/react");
class DashboardUppy extends React.Component {
constructor(props) {
super(props);
this.form = React.createRef();
this.state = {
showInlineDashboard: false,
open: false,
};
this.uppy = new Uppy({
id: "uppy1",
autoProceed: false,
debug: true,
allowMultipleUploads: true,
showSelectedFiles: true,
restrictions: {
maxFileSize: 1000000,
maxNumberOfFiles: 100,
minNumberOfFiles: 1,
allowedFileTypes: ['image/*', 'video/*'],
},
onBeforeFileAdded: (currentFile, files) => {
console.log(files);
const modifiedFile = Object.assign({}, currentFile, {
name: currentFile + Date.now(),
});
if (!currentFile.type) {
// log to console
this.uppy.log(`Skipping file because it has no type`);
// show error message to the user
this.uppy.info(`Skipping file because it has no type`, "error", 500);
return false;
}
return modifiedFile;
},
})
.use(Tus, { endpoint: "https://master.tus.io/files/" })
.use(GoogleDrive, { companionUrl: "https://companion.uppy.io" })
.use(Dropbox, {
companionUrl: "https://companion.uppy.io",
})
.use(Instagram, {
companionUrl: "https://companion.uppy.io",
})
.use(Webcam, {
onBeforeSnapshot: () => Promise.resolve(),
countdown: false,
modes: ["video-audio", "video-only", "audio-only", "picture"],
mirror: true,
facingMode: "user",
locale: {
strings: {
// Shown before a picture is taken when the `countdown` option is set.
smile: "Smile!",
// Used as the label for the button that takes a picture.
// This is not visibly rendered but is picked up by screen readers.
takePicture: "Take a picture",
// Used as the label for the button that starts a video recording.
// This is not visibly rendered but is picked up by screen readers.
startRecording: "Begin video recording",
// Used as the label for the button that stops a video recording.
// This is not visibly rendered but is picked up by screen readers.
stopRecording: "Stop video recording",
// Title on the “allow access” screen
allowAccessTitle: "Please allow access to your camera",
// Description on the “allow access” screen
allowAccessDescription:
"In order to take pictures or record video with your camera, please allow camera access for this site.",
},
},
})
.on("file-added", (file) => {
const { setFiles } = props;
setFiles(file);
})
}
componentWillUnmount() {
this.uppy.close();
}
render() {
this.uppy.on("complete", (result) => {
console.log(
"Upload complete! We’ve uploaded these files:",
result.successful
);
});
return (
<div>
<div>
<Dashboard
uppy={this.uppy}
plugins={["GoogleDrive", "Webcam", "Dropbox", "Instagram"]}
metaFields={[
{ id: "name", name: "Name", placeholder: "File name" },
]}
open={this.state.open}
target={document.body}
onRequestClose={() => this.setState({ open: false })}
/>
</div>
</div>
);
}
}
export default DashboardUppy;
And I use it like this nothing special:
import React, { useState } from "react";
import FileList from "./FileList";
import FileForm from "./FileForm";
import DashboardUppy from "./DashboardUppy";
import { Container, Grid } from "#material-ui/core";
const CreateContent = () => {
const [file, setItems] = useState();
const [show, showDashboardUppy] = useState(true);
return (
<Container maxWidth="lg">
{show ? (
<DashboardUppy showDashboardUppy={showDashboardUppy}/>
) : (
<Grid container spacing={3}>
<Grid item lg={4} md={6} xs={12}>
<FileList setItems={setItems} />
</Grid>
<Grid item lg={8} md={6} xs={12}>
<FileForm file={file} />
</Grid>
</Grid>
)}
</Container>
);
};
export default CreateContent;
Here is package.json
{
"name": "react-firestore-crud",
"version": "0.1.0",
"private": true,
"dependencies": {
"#uppy/core": "1.0.2",
"#uppy/dropbox": "latest",
"#uppy/form": "^1.3.23",
"#uppy/google-drive": "1.0.2",
"#uppy/instagram": "1.0.2",
"#uppy/react": "^1.0.2",
"#uppy/status-bar": "latest",
"#uppy/tus": "1.0.2",
"#uppy/webcam": "latest",
"#uppy/xhr-upload": "^1.6.8",
"#material-ui/core": "^4.11.2",
"#material-ui/icons": "^4.11.2",
"#material-ui/lab": "^4.0.0-alpha.57",
"#material-ui/styles": "^4.11.2",
"#testing-library/jest-dom": "^4.2.4",
"#testing-library/react": "^9.3.2",
"#testing-library/user-event": "^7.1.2",
"bootstrap": "^4.5.2",
"clsx": "^1.1.1",
"firebase": "^7.23.0",
"moment": "^2.29.1",
"prop-types": "^15.7.2",
"react": "^16.8.4",
"react-dom": "^16.8.4",
"react-perfect-scrollbar": "^1.5.8",
"react-router-dom": "^5.2.0",
"react-scripts": "^3.4.0",
"uuid": "^8.3.2"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}
I hade the wrong Uppy version in package.json hmmm

How to use Fine Uploader in React js

Hi i am newbie to Reactjs. i am using fineuploader to upload files to the server.i want to create a FineUploader Component ,so that i can use it where ever i want.
package.json
{
"name": "Sample",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"babel-core": "^6.2.1",
"babel-loader": "^6.2.0",
"babel-preset-es2015": "^6.1.18",
"babel-preset-react": "^6.1.18",
"fine-uploader": "^5.7.1",
"react": "^0.14.6",
"react-dom": "^0.14.6",
"webpack": "^1.12.9",
"webpack-dev-server": "^1.14.0"
}
}
webpack.config.js
var path = require("path");
module.exports = {
entry: [
'./Components/Main.js'
],
output:{
path:__dirname,
filename:'bundle.js'
},
resolve: {
alias: {
'fine-uploader': path.resolve('node_modules/fine-uploader/fine-uploader')
}
},
module:{
loaders: [
{
test: /fine-uploader\.js/,
loader: 'exports?qq'
}
],
loaders:[{
test: /\.jsx?$/,
exclude:/node_modules/,
loader:'babel',
query:{
presets: ['react']
}
}]
}
};
FineUploader.js
import React from 'react';
import qq from 'fine-uploader/fine-uploader';
class FineUploader extends React.Component {
constructor (props) {
super(props)
}
componentDidMount () {
const fu = new qq.FineUploaderBasic({
button: this.refs.fu
})
}
render () {
return <div ref='fu'>Upload!</div>
}
}
export default FineUploader;
Main.js
import React from 'react';
import ReactDOM from 'react-dom';
import FineUploader from './FineUploader.js';
var MainContent = React.createClass({
render:function(){
return (
<div>
<FineUploader />
</div>
);
}
});
ReactDOM.render(<MainContent />,document.getElementById('container'));
When i run the Application i am getting the below error
uncaught TypeError: _fineUploader2.default.FineUploaderBasic is not a constructor
i dint no what i am doing wrong ,Plz somebody guide me
To use Fine Uploader with React you will need to create a new uploader instance within the componentDidMount lifecycle method.
Invoked once, only on the client (not on the server), immediately after the initial rendering occurs. At this point in the lifecycle, you can access any refs to your children (e.g., to access the underlying DOM representation).
Fine Uploader needs an actual rendered DOM element for it to attach event handlers, render other DOM elements as children, etc.
Inside of componentDidMount we not only know our component has been created, but we also have a DOM element and we can reference it as such using a ref.
Here's a tiny example component:
class FineUploader extends React.Component {
componentDidMount () {
const fu = new qq.s3.FineUploaderBasic({
button: this.refs.fu
})
}
render () {
return <div ref='fu'>Upload!</div>
}
}
Even though my answer is not completely relevant to the asked question but I would recommend the react-fine-uploader library to make your life easier.
https://github.com/FineUploader/react-fine-uploader

Resources