Skip to content

Commit

Permalink
Import warnings that currently live in gists. (#7175)
Browse files Browse the repository at this point in the history
  • Loading branch information
zpao committed Jul 5, 2016
1 parent 69703e0 commit 26ed910
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
58 changes: 58 additions & 0 deletions docs/warnings/legacy-factories.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
---
title: React Element Factories and JSX Warning
layout: single
---

You probably came here because your code is calling your component as a plain function call. This is now deprecated:

```javascript
var MyComponent = require('MyComponent');

function render() {
return MyComponent({ foo: 'bar' }); // WARNING
}
```

## JSX

React components can no longer be called directly like this. Instead [you can use JSX](/react/docs/jsx-in-depth.html).

```javascript
var React = require('react');
var MyComponent = require('MyComponent');

function render() {
return <MyComponent foo="bar" />;
}
```

## Without JSX

If you don't want to, or can't use JSX, then you'll need to wrap your component in a factory before calling it:

```javascript
var React = require('react');
var MyComponent = React.createFactory(require('MyComponent'));

function render() {
return MyComponent({ foo: 'bar' });
}
```

This is an easy upgrade path if you have a lot of existing function calls.

## Dynamic components without JSX

If you get a component class from a dynamic source, then it might be unnecessary to create a factory that you immediately invoke. Instead you can just create your element inline:

```javascript
var React = require('react');

function render(MyComponent) {
return React.createElement(MyComponent, { foo: 'bar' });
}
```

## In Depth

[Read more about WHY we're making this change.](https://gist.github.com/sebmarkbage/d7bce729f38730399d28)
26 changes: 26 additions & 0 deletions docs/warnings/refs-must-have-owner.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
title: Refs Must Have Owner Warning
layout: single
---

You are probably here because you got the following error messages:

> Warning:
>
> addComponentAsRefTo(...): Only a ReactOwner can have refs. You might be adding a ref to a component that was not created inside a component's `render` method, or you have multiple copies of React loaded.
This usually means one of two things:

- You are trying to add a `ref` to an element that is being created outside of a component's render() function.
- You have multiple (conflicting) copies of React loaded (eg. due to a miss-configured NPM dependency)


## Invalid Refs

Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's `render` method). Try rendering this component inside of a new top-level component which will hold the ref.

## Multiple copies of React

Bower does a good job of deduplicating dependencies, but NPM does not. If you aren't doing anything (fancy) with refs, there is a good chance that the problem is not with your refs, but rather an issue with having multiple copies of React loaded into your project. Sometimes, when you pull in a third-party module via npm, you will get a duplicate copy of the dependency library, and this can create problems.

If you are using npm... `npm ls` or `npm ls | grep react` might help illuminate.
8 changes: 8 additions & 0 deletions docs/warnings/special-props.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
title: Special Props Warning
layout: single
---

Most props on a JSX element are passed on to the component, however, there are two special props (`ref` and `key`) which are used by React, and are thus not forwarded to the component.

For instance, attempting to access `this.props.key` from a component (eg. the render function) is not defined. If you need to access the same value within the child component, you should pass it as a different prop (ex: `<ListItemWrapper key={result.id} id={result.id} />`). While this may seem redundant, it's important to separate app logic from reconciling hints.
60 changes: 60 additions & 0 deletions docs/warnings/unknown-prop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
title: Unknown Prop Warning
layout: single
---
The unknown-prop warning will fire if you attempt to render a DOM element with a prop that is not recognized by React as a legal DOM attribute/property. You should ensure that your DOM elements do not have spurious props floating around.

There are a couple of likely reasons this warning could be appearing:

1. Are you using `{...this.props}` or `cloneElement(element, this.props)`? Your component is transferring its own props directly to a child element (eg. https://facebook.github.io/react/docs/transferring-props.html). When transferring props to a child component, you should ensure that you are not accidentally forwarding props that were intended to be interpreted by the parent component.

2. You are using a non-standard DOM attribute on a native DOM node, perhaps to represent custom data. If you are trying to attach custom data to a standard DOM element, consider using a custom data attribute as described [on MDN](https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes).

3. React does not yet recognize the attribute you specified. This will likely be fixed in a future version of React. However, React currently strips all unknown attributes, so specifying them in your React app will not cause them to be rendered.

---

To fix this, composite components should "consume" any prop that is intended for the composite component and not intended for the child component. Example:

**Bad:** Unexpected `layout` prop is forwarded to the `div` tag.

```js
function MyDiv(props) {
if (props.layout === 'horizontal') {
// BAD! Because you know for sure "layout" is not a prop that <div> understands.
return <div {...props} style={getHorizontalStyle()} />
} else {
// BAD! Because you know for sure "layout" is not a prop that <div> understands.
return <div {...props} style={getVerticalStyle()} />
}
}
```

**Good:** The spread operator can be used to pull variables off props, and put the remaining props into a variable.

```js
function MyDiv(props) {
const { layout, ...rest } = props
if (layout === 'horizontal') {
return <div {...rest} style={getHorizontalStyle()} />
} else {
return <div {...rest} style={getVerticalStyle()} />
}
}
```

**Good:** You can also assign the props to a new object and delete the keys that you're using from the new object. Be sure not to delete the props from the original `this.props` object, since that object should be considered immutable.

```js
function MyDiv(props) {

const divProps = Object.assign({}, props);
delete divProps.layout;

if (props.layout === 'horizontal') {
return <div {...divProps} style={getHorizontalStyle()} />
} else {
return <div {...divProps} style={getVerticalStyle()} />
}
}
```

0 comments on commit 26ed910

Please sign in to comment.