Explorar o código

Improve react docs (#1936)

Co-authored-by: Renée Kooi <renee@kooi.me>
Pedro Fernandes Steimbruch %!s(int64=4) %!d(string=hai) anos
pai
achega
f54c6dad99

+ 12 - 29
website/src/docs/react-dashboard-modal.md

@@ -3,7 +3,7 @@ title: "&lt;DashboardModal />"
 type: docs
 module: "@uppy/react"
 permalink: docs/react/dashboard-modal/
-order: 5
+order: 6
 category: "React"
 ---
 
@@ -39,35 +39,8 @@ Import general Core styles from `@uppy/core/dist/style.css` first, then add the
 
 Styles for Provider plugins, like Google Drive and Instagram, are also bundled with Dashboard styles. Styles for other plugins, such as `@uppy/url` and `@uppy/webcam`, are not inluded. If you are using those, please see their docs and make sure to include styles for them as well.
 
-## Initializing Uppy
-
-Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
-
-> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
-> Do **NOT** initialize Uppy in a `render()` method!
-> Do **NOT** initialize Uppy in a function component!
-
-```js
-class MyComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.uppy = Uppy()
-      .use(Transloadit, {})
-  }
-
-  componentWillUnmount () {
-    this.uppy.close()
-  }
-
-  render () {
-    return <DashboardModal uppy={this.uppy} />
-  }
-}
-```
-
 <!-- Make sure the old name of this section still works -->
 <a id="Options"></a>
-
 ## Props
 
 On top of all the [`@uppy/dashboard`][] options, the `<DashboardModal />` plugin adds two additional props:
@@ -75,6 +48,8 @@ On top of all the [`@uppy/dashboard`][] options, the `<DashboardModal />` plugin
  - `open` - Boolean true or false, setting this to `true` opens the modal and setting it to `false` closes it.
  - `onRequestClose` - Callback called when the user attempts to close the modal, either by clicking the close button or by clicking outside the modal (if the `closeModalOnClickOutside` prop is set).
 
+An Uppy instance must be provided in the `uppy={}` prop: see [Initializing Uppy](/docs/react/initializing) for details.
+
 To use other plugins like [`@uppy/webcam`][] with the `<DashboardModal />` component, add them to the Uppy instance and then specify their `id` in the [`plugins`](/docs/dashboard/#plugins) prop:
 
 ```js
@@ -97,10 +72,18 @@ class MusicUploadButton extends React.Component {
       modalOpen: false
     }
 
+    this.uppy = new Uppy()
+      .use(XHRUpload, { endpoint: '/api/songs/upload' })
+      .use(Webcam, { modes: ['audio-only'] })
+
     this.handleOpen = this.handleOpen.bind(this)
     this.handleClose = this.handleClose.bind(this)
   }
 
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
   handleOpen () {
     this.setState({
       modalOpen: true
@@ -118,7 +101,7 @@ class MusicUploadButton extends React.Component {
       <div>
         <button onClick={this.handleOpen}>Upload some music</button>
         <DashboardModal
-          uppy={this.props.uppy}
+          uppy={this.uppy}
           closeModalOnClickOutside
           open={this.state.modalOpen}
           onRequestClose={this.handleClose}

+ 21 - 41
website/src/docs/react-dashboard.md

@@ -3,7 +3,7 @@ title: "&lt;Dashboard />"
 type: docs
 module: "@uppy/react"
 permalink: docs/react/dashboard/
-order: 4
+order: 5
 category: "React"
 ---
 
@@ -39,52 +39,32 @@ Import general Core styles from `@uppy/core/dist/style.css` first, then add the
 
 Styles for Provider plugins, like Google Drive and Instagram, are also bundled with Dashboard styles. Styles for other plugins, such as `@uppy/url` and `@uppy/webcam`, are not inluded. If you are using those, please see their docs and make sure to include styles for them as well.
 
-## Initializing Uppy
-
-Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
-
-> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
-> Do **NOT** initialize Uppy in a `render()` method!
-> Do **NOT** initialize Uppy in a function component!
-
-```js
-class MyComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.uppy = Uppy()
-      .use(Transloadit, {})
-  }
-
-  componentWillUnmount () {
-    this.uppy.close()
-  }
-
-  render () {
-    return <Dashboard uppy={this.uppy} />
-  }
-}
-```
-
 ## Props
 
-The `<Dashboard />` component supports all [`@uppy/dashboard`][] options as props.
+The `<Dashboard />` component supports all [`@uppy/dashboard`][] options as props. Additionally, an Uppy instance must be provided in the `uppy={}` prop: see [Initializing Uppy](/docs/react/initializing) for details.
 
 The `<Dashboard />` cannot be passed to a `target:` option of a remote provider or plugins such as [`@uppy/webcam`][]. To use other plugins like [`@uppy/webcam`][] with the `<Dashboard />` component, first add them to the Uppy instance, and then specify their `id` in the [`plugins`](/docs/dashboard/#plugins) prop:
 
 ```js
-// Do this wherever you initialize Uppy, e.g., in a React component's constructor method.
-// Do NOT do it in `render()` or any other method that is called more than once!
-uppy.use(Webcam) // `id` defaults to "Webcam"
-uppy.use(Webcam, { id: 'MyWebcam' }) // `id` is… "MyWebcam"
-```
-
-Then add the following to `render()`:
-
-```js
-<Dashboard
-  plugins={['Webcam']}
-  {...props}
-/>
+function Uploader () {
+  const uppy = React.useMemo(() => {
+    return Uppy()
+      .use(Webcam) // `id` defaults to "Webcam"
+      // or
+      .use(Webcam, { id: 'MyWebcam' }) // `id` is… "MyWebcam"
+  }, [])
+  React.useEffect(() => {
+    return () => uppy.close()
+  }, [])
+
+  return (
+    <Dashboard
+      uppy={uppy}
+      plugins={['Webcam']}
+      {...props}
+    />
+  )
+}
 ```
 
 [`@uppy/dashboard`]: /docs/dashboard/

+ 2 - 28
website/src/docs/react-dragdrop.md

@@ -4,7 +4,7 @@ type: docs
 module: "@uppy/react"
 permalink: docs/react/drag-drop/
 alias: docs/react/dragdrop/
-order: 2
+order: 3
 category: "React"
 ---
 
@@ -36,35 +36,9 @@ import '@uppy/drag-drop/dist/style.css'
 
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Drag & Drop styles from `@uppy/drag-drop/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 
-## Initializing Uppy
-
-Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
-
-> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
-> Do **NOT** initialize Uppy in a `render()` method!
-> Do **NOT** initialize Uppy in a function component!
-
-```js
-class MyComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.uppy = Uppy()
-      .use(Transloadit, {})
-  }
-
-  componentWillUnmount () {
-    this.uppy.close()
-  }
-
-  render () {
-    return <DragDrop uppy={this.uppy} />
-  }
-}
-```
-
 ## Props
 
-The `<DragDrop />` component supports all [DragDrop](/docs/drag-drop/) options as props.
+The `<DragDrop />` component supports all [DragDrop](/docs/drag-drop/) options as props. Additionally, an Uppy instance must be provided in the `uppy={}` prop: see [Initializing Uppy](/docs/react/initializing) for details.
 
 ```js
 // assuming `this.uppy` contains an Uppy instance:

+ 73 - 0
website/src/docs/react-initializing.md

@@ -0,0 +1,73 @@
+---
+title: "Initializing Uppy"
+type: docs
+module: "@uppy/react"
+permalink: docs/react/initializing/
+alias: docs/react/initializing/
+order: 1
+category: "React"
+---
+
+When using Uppy's React components, an Uppy instance must be passed in to the `uppy={}` prop from the outside. This Uppy instance must be initialized before passing it to the desired component, and be cleaned up using `uppy.close()` when you are done with it.
+
+## Functional Components
+
+With React Hooks, the `useMemo` hook can be used to create an instance once and remember it for all rerenders. The `useEffect` hook can close the Uppy instance when the component unmounts.
+
+```js
+const MyComponent = () => {
+  const uppy = React.useMemo(() => {
+    // Do all the configuration here
+    return Uppy()
+      .use(Transloadit, {})
+  }, []);
+
+  React.useEffect(() => {
+    return () => uppy.close()
+  }, [])
+
+  return <DashboardModal uppy={uppy} />
+}
+```
+
+Both hooks must receive the `[]` dependency array parameter, or the Uppy instance will be recreated and/or destroyed every time the component rerenders. To make sure you never forget that, a custom hook could be used:
+```js
+function useUppy (factory) {
+  const uppy = React.useMemo(factory, [])
+  React.useEffect(() => {
+    return () => uppy.close()
+  }, [])
+  return uppy
+}
+
+// Then use it as:
+const uppy = useUppy(() => {
+  return Uppy()
+    .use(Tus, {})
+})
+```
+
+## Class Components
+
+A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
+
+> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
+> Do **NOT** initialize Uppy in a `render()` method!
+
+```js
+class MyComponent extends React.Component {
+  constructor (props) {
+    super(props)
+    this.uppy = Uppy()
+      .use(Transloadit, {})
+  }
+
+  componentWillUnmount () {
+    this.uppy.close()
+  }
+
+  render () {
+    return <DashboardModal uppy={this.uppy} />
+  }
+}
+```

+ 1 - 46
website/src/docs/react-native.md

@@ -3,7 +3,7 @@ title: "React Native"
 type: docs
 module: "@uppy/react-native"
 permalink: docs/react/native/
-order: 7
+order: 8
 category: "React"
 ---
 
@@ -35,51 +35,6 @@ render () {
 }
 ```
 
-## Initializing Uppy
-
-Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
-
-> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
-> Do **NOT** initialize Uppy in a `render()` method!
-> Do **NOT** initialize Uppy in a function component!
-
-```js
-class MyComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.state = {
-      isFilePickerVisible: false
-    }
-    this.uppy = Uppy()
-      .use(Transloadit, {})
-  }
-
-  componentWillUnmount () {
-    this.uppy.close()
-  }
-
-  showFilePicker () {
-    this.setState({
-      isFilePickerVisible: true
-    })
-  }
-
-  hideFilePicker () {
-    this.setState({
-      isFilePickerVisible: false
-    })
-  }
-
-  render () {
-    return <UppyFilePicker
-      show={this.state.isFilePickerVisible}
-      uppy={this.uppy}
-      onRequestClose={this.hideFilePicker}
-      companionUrl="https://companion.uppy.io" />
-  }
-}
-```
-
 ## Props
 
 The `<UppyFilePicker>` component supports the following props:

+ 3 - 28
website/src/docs/react-progressbar.md

@@ -4,7 +4,7 @@ type: docs
 module: "@uppy/react"
 permalink: docs/react/progress-bar/
 alias: docs/react/progressbar/
-order: 3
+order: 4
 category: "React"
 ---
 
@@ -36,38 +36,13 @@ import '@uppy/progress-bar/dist/style.css'
 
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Progress Bar styles from `@uppy/progress-bar/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 
-## Initializing Uppy
-
-Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
-
-> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
-> Do **NOT** initialize Uppy in a `render()` method!
-> Do **NOT** initialize Uppy in a function component!
-
-```js
-class MyComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.uppy = Uppy()
-      .use(Transloadit, {})
-  }
-
-  componentWillUnmount () {
-    this.uppy.close()
-  }
-
-  render () {
-    return <ProgressBar uppy={this.uppy} />
-  }
-}
-```
-
 ## Props
 
-The `<ProgressBar />` component supports all [`@uppy/progress-bar`][] options as props.
+The `<ProgressBar />` component supports all [`@uppy/progress-bar`][] options as props. Additionally, an Uppy instance must be provided in the `uppy={}` prop: see [Initializing Uppy](/docs/react/initializing) for details.
 
 ```js
 <ProgressBar
+  uppy={uppy}
   fixed
   hideAfterFinish
 />

+ 3 - 28
website/src/docs/react-statusbar.md

@@ -4,7 +4,7 @@ type: docs
 module: "@uppy/react"
 permalink: docs/react/status-bar/
 alias: docs/react/statusbar/
-order: 1
+order: 2
 category: "React"
 ---
 
@@ -36,38 +36,13 @@ import '@uppy/status-bar/dist/style.css'
 
 Import general Core styles from `@uppy/core/dist/style.css` first, then add the Status Bar styles from `@uppy/status-bar/dist/style.css`. A minified version is also available as `style.min.css` at the same path. The way to do import depends on your build system.
 
-## Initializing Uppy
-
-Your Uppy instance must be initialized before passing it to an `uppy={}` prop, and should be cleaned up using `uppy.close()` when you are done with it. A simple approach is to initialize it in your React component's `constructor()` and destroy it in `componentWillUnmount()`.
-
-> ⚠ Uppy instances are stateful, so the same instance must be used across different renders.
-> Do **NOT** initialize Uppy in a `render()` method!
-> Do **NOT** initialize Uppy in a function component!
-
-```js
-class MyComponent extends React.Component {
-  constructor (props) {
-    super(props)
-    this.uppy = Uppy()
-      .use(Transloadit, {})
-  }
-
-  componentWillUnmount () {
-    this.uppy.close()
-  }
-
-  render () {
-    return <StatusBar uppy={this.uppy} />
-  }
-}
-```
-
 ## Props
 
-The `<StatusBar />` component supports all [`@uppy/status-bar`][] options as props.
+The `<StatusBar />` component supports all [`@uppy/status-bar`][] options as props. Additionally, an Uppy instance must be provided in the `uppy={}` prop: see [Initializing Uppy](/docs/react/initializing) for details.
 
 ```js
 <StatusBar
+  uppy={uppy}
   hideUploadButton
   hideAfterFinish={false}
   showProgressDetails