我使用React已经很长时间了,我遇到了一个有趣的问题:基本上,我想使用defaultProps
作为 fallbackProps
- 这就是他们的意思是的,但有一个难点 - 来自无状态/ defaultProps
API的class extend Component
属性和来自getDefaultProps()
API的缓存React.createClass
都是不可变的(和常量)。
示例:
var ExampleComponent = React.createClass({
getDefaultProps: function () {
return {
number: Math.random()
};
}
// ...
});
// or equivalent with ES6 classes
class ExampleComponent extends React.Component {
// ...
}
ExampleComponent.defaultProps = {
number: Math.random()
};
// then...
<main>
<ExampleComponent /> // cached random
<ExampleComponent /> // cached random
<ExampleComponent number={1} /> // 1
<ExampleComponent /> // cached random
<ExampleComponent /> // cached random
</main>
问题是,我希望动态 defaultProps
- 为每个组件实例分开。
示例:
<main>
<ExampleComponent /> // fresh random
<ExampleComponent /> // fresh random
<ExampleComponent number={1} /> // 1
<ExampleComponent /> // fresh random
<ExampleComponent /> // fresh random
</main>
我知道,使用state
(getInitialState
每个组件)很容易实现这种行为,但我想知道是否有可能没有状态和没有HOC或类似方法。
答案 0 :(得分:4)
是。这可以通过使用ES5 getter来定义defaultProps
对象:
ExampleComponent.defaultProps = Object.create({}, {
number: {
enumerable: true,
get: () => Math.random()
}
});
正如您所注意到的,defaultProps
是一个静态成员,因此每个类只会初始化一次。但是,当调用React.createElement
时,它会通过枚举所有属性并将它们复制到一个新的空白对象来创建defaultProps
的新副本(此枚举是enumerable: true
必须的原因在描述符中设置)。 Relevant part of React's source:
// Resolve default props
if (type && type.defaultProps) {
var defaultProps = type.defaultProps;
for (propName in defaultProps) {
if (props[propName] === undefined) {
props[propName] = defaultProps[propName];
}
}
}
defaultProps[propName]
调用getter,它会生成一个新的随机数,然后存储在props
中。
答案 1 :(得分:0)
我的模态需要一个随机的“唯一”ID,这就是我执行以下操作的原因:
const Modal = () => { // my component
const id = useMemo(() => {
// this will be run only once on "mount"
return `modal-${randomNumber(1111,9999)}`;
}, []); // empty array is important!
return <div id={id}>Model {id}</div>;
};
/**
* Random number between min (including) and max (excluding)
* @param {number} min
* @param {number} max
* @return {number}
*/
const randomNumber = (min, max) => {
return Math.floor(
(Math.random() * (max - min)) + min
);
};
这是您问题的一种解决方案,只是它不使用 defaultProps
。另一方面,它不会在每次重新渲染时为您提供随机 ID,例如 @quw 解决方案。
也许它对某些人有用。