PropTypes
๊ฐ prop์ '์ ํ'์ ๋ํ ๊ฒ์ด๋ฏ๋ก null
๋ ๋น ๊ฐ์ฒด์ด์ง๋ง ์ค์ ๋ก๋ ์ฌ์ ํ ๊ฐ์ฒด ์ ํ์
๋๋ค.
๊ทธ๋ฌ๋ ์ฌ์ ํ ๋ค์๊ณผ ๊ฐ์ด ๊ฒฝ๊ณ ํฉ๋๋ค.
Warning: Required prop `profile` was not specified in `Element`. Check the render method of `OtherElement`.
๋๋ ์ด๊ฒ์ด ์ผ์ด๋์๋ ์๋๋ค๊ณ ์๊ฐํ๋ค.
๋ ์ด์ null
๊ฐ ์๋ ํ์ ๊ฒฝ๊ณ ๋ฅผ ์ค์งํฉ๋๋ค. undefined
๋๋ง ๊ฒฝ๊ณ ํด์ผ ํ๋ค๊ณ ํ์ ํฉ๋๋ค.
null
๋ ๊ฐ์ด ์๋ ๊ฒ๊ณผ ๋์ผํ๋ฉฐ ๊ฐ์ฒด๊ฐ ์๋๋๋ค(๋น์ด ์๊ฑฐ๋ ๊ทธ๋ ์ง ์์ ๊ฒฝ์ฐ). null
์ ๋ํด ๊ฒฝ๊ณ ํ์ง ์์ผ๋ ค๋ฉด ํ์ ํญ๋ชฉ์ผ๋ก ์ง์ ํ์ง ์์๋ ๋์ผํ ํจ๊ณผ๊ฐ ์์ต๋๋ค. ํค์ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ
์คํธํ๋ ๊ฒ์ ๋ด๊ฐ ๊ถ์ฅํ๋ ๊ฒ์ด ์๋๋๋ค.
๋๋ ๋์ํ๋ค. ์ฌ์ฉ์์๊ฒ ๊ฐ์ ์ง์ ํ๋๋ก ๊ฐ์ ํ๊ณ ์ถ์ง๋ง null์ ์ ํจํ ๊ฐ์ผ๋ก ๊ธฐ๊บผ์ด ๋ฐ์๋ค์ด๋ ์ฌ์ฉ ์ฌ๋ก๋ ๋ง์ง ์์ต๋๋ค. ์ค์ฉ์ ์ธ ๋ชฉ์ ์ ์ํด null์ ๋ํ isRequired ๊ฒฝ๊ณ ๋ ํฉ๋ฆฌ์ ์ด๊ณ ์์๋๋ ๋์์ ๋๋ค.
๊ด๋ จ: https://github.com/facebook/react/issues/2166
(์ด ๋ฌธ์ ๋ ์ฌ์ ํ ๊ฒ์ ๊ฒฐ๊ณผ์ ๋๋๋ฌ์ง๊ฒ ๋ํ๋ฉ๋๋ค)
๋ด๊ฐ ๋ณด๋ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ ๋ฐ์ดํฐ์ ๋ํ API ํธ์ถ์ด ์๋ฃ๋๊ธฐ ์ ์ ๊ตฌ์ฑ ์์๋ฅผ ๋ ๋๋งํ๋ React์
๋๋ค. ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์ ์๋ฅผ ๋ค์ด ํญ๋ชฉ ๋ชฉ๋ก( items: null
)์ ๋ ๋๋งํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ API ํธ์ถ์ด ์๋ฃ๋๊ณ ์ด์ items
๊ฐ ๋ฐฐ์ด๋ก ์ฑ์์ง๋๋ค.
๋๋ PropTypes.oneOfType([null, PropTypes.object]).isRequired
์๋ํ๊ณ ์์ผ๋ฏ๋ก null ๋๋ ๊ฐ์ฒด ์ค ํ๋๊ฐ ํ์ฌ ๊ฐ๋ฅํ์ง ์์ต๋๊น?
CHANGELOG ์ ๋ฐ๋ฅด๋ฉด 15.4.0
์ดํ๋ก ๊ฐ๋ฅํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค.
์ฌ์ค, 15.4.0์์๋ ๋ฐ๋์
๋๋ค: Required PropTypes now fail with specific messages for null and undefined.
๋๋ ๋ํ์ด ๋ฌธ์ ์ ์ง๋ฉด ํด ์์ต๋๋ค.
@Noitidart ์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ด ์๋ํ์ง ์์ต๋๋ค. ๋ค์๊ณผ ๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
Failed prop type: The prop
๊ฐ is marked as required in
, but its value is
null .
์์ฑ์ด ํ์ํ์ง๋ง null ๊ฐ๋ ํ์ฉํ๋ ๊ฒ์ด ์ ๋ง ์ ์ฉํ๋ค๋ ๊ฒ์ ์์์ต๋๋ค.
null
์ด๋ป๊ฒ๋ ํ์ฉํ ๊ฒ์ ๋ํด +1์
๋๋ค.
๊ตฌ์ฑ์ด JSON์ ํตํด ๋ก๋๋๋ ์ฌ์ฉ ์ฌ๋ก๊ฐ ์์ผ๋ฉฐ ๋ค์๊ณผ ๊ฐ์ด ํ์๋์ด์ผ ํ๋ ๋ฌธ์์ด์ ์ง์ ํ๋ ์ฌ๋ฌ ๋ ์ด๋ธ ๊ตฌ์ฑ ์ต์ ์ด ์์ต๋๋ค.
{
"title": "my title"
}
๋ฐ๋ผ์ ์ ๋ชฉ์ ํ์ํ์ง ์์์ผ ํ๋ ๊ฒฝ์ฐ null
๋ฅผ ์ฌ์ฉํ์ฌ ํด๋น ์ฌ๋ก๋ฅผ ๋ํ๋
๋๋ค.
{
"title": null
}
(์ด๋ฌํ ์ค์ ์ด ์์ญ ๊ฐ ์์ผ๋ฏ๋ก ๋ณ๋ ฌ hasTitle: false
๋ฅผ ์ถ๊ฐํ๋ ๊ฒ์ ๊ธ์ง๋ฉ๋๋ค.)
JSON ์ฝํ
์ธ ์ ๊ฒฝ์ฐ null์ ์ฌ์ฉํ๋ ๊ฒ์ ์ ์๋์ง ์์ ๊ฒ( undefined
)๊ณผ ์๋์ ์ผ๋ก ์๋ต๋ ๊ฒ( null
)์ ๊ตฌ๋ณํ๋ ๋งค์ฐ ์ ์ฉํ ๋ฐฉ๋ฒ์
๋๋ค.
null์ ํ์ฉํ ์ ์์ต๋๋ค. propType์ ํ์๊ฐ ์๋๋ฏ๋ก ํ์ํ์ง ์๋๋ก ์ค์ ํ์ญ์์ค.
@jquense ๊ฐ์ฌํฉ๋๋ค ๋งค์ฐ ๋์์ด ๋ฉ๋๋ค! ์ด SO ๋ต๋ณ ์ด ๊ฐ์ ๋ด์ฉ์ ๋งํ๊ธฐ ๋๋ฌธ์ ์ด์ ์๊ฒฌ์ ์ญ์ ํ์ต๋๋ค.
@jquense null AND undefined๋ ํ์ฉํ ์ ์์ง๋ง ๋ ์ค ํ๋๋ ํ์ฉํ์ง ์์ต๋๋ค.
๊ทธ๊ฒ์ด ๋ชจ๋ ๋ฌธ์ ์
๋๋ค! Javascript๋ ์ด๋ฌํ 2๊ฐ์ง ๋ค๋ฅธ ๊ตฌ์ฑ์ ์ ๊ณตํ ๋ฐ๋ ์ด์ ๊ฐ ์์ผ๋ฏ๋ก ๋ชจ๋ ์ฌ๋์ด PropTypes์ ๋ํด null === undefined
๋ฅผ ์ฒ๋ฆฌํ๋๋ก ํ๋ ๊ฒ์ ์ธ์์ ์ธ ์ ํ์
๋๋ค.
PropType์ด null์ ๋ช ์์ ์ผ๋ก ํ์ฉํ๊ธฐ๋ฅผ ์ํ๋ค๊ณ ํด์ undefined๋ ํ์ฉํด์ผ ํ๋ค๋ ์๋ฏธ๋ ์๋๋๋ค. ๊ทธ๋ค์ ๋ ๊ฐ์ง ๋ณ๊ฐ์ ๊ฒฝ์ฐ์ด๋ฉฐ ์ธ์ด๋ ์๋์ ์ผ๋ก ๊ทธ๋ ๊ฒ ์ค๊ณํ์ต๋๋ค.
์ฌ๊ธฐ์์ ์ด ๊ฐ๋ ์ ํด๊ฒฐํ๊ธฐ ์ํ PR์ด ์์ต๋๋ค: https://github.com/facebook/prop-types/pull/90
undefined
๋ฅผ ํ์ฉํ์ง ์๋ ์ด์ ๋ ์คํ๊ฐ ์์์ ์๋ฏธํ๊ณ null
ํ์ฉํ๋ค๋ ๊ฒ์ ํธ์ถ์๊ฐ null
๋ช
์์ ์ผ๋ก ์ ๋ฌํ์์ ์๋ฏธํ๊ธฐ ๋๋ฌธ์
๋๋ค. ์ด๊ฒ์ด ์ด ๋ฌธ์ ์ ์์ ์
๋๋ค. ํ๋ฆ์ผ๋ก ์ ํํ๋ ๊ฒ์ด ๊ถ์ฅ๋๊ธฐ ๋๋ฌธ์ ์ด ๋ฌธ์ ๊ฐ ์ข
๋ฃ๋์์์ ์ดํดํฉ๋๋ค.
@binki null
ํ์ง๋ง undefined
๋ ํ์ฉํ์ง ์๋ ํ ๊ฐ์ง ๋ฐฉ๋ฒ์ ๊ณ ์ ํ PropType ์ ํจ์ฑ ๊ฒ์ฌ๊ธฐ ๊ธฐ๋ฅ์ ์ฌ์ฉํ๋ ๊ฒ์
๋๋ค.
์๋ ์์์๋ null
๋๋ string
๋ง ํ์ฉ๋ฉ๋๋ค. PropTypes ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ๋ด๋ถ์ ์ผ๋ก typeof
๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์์ด์ ํ์ธํ๋ฏ๋ก ๋์ผํ ์์
์ ์ํํ์ต๋๋ค. ํ ๊ฐ์ง ์ด์ ์ ์ด ํจ์๋ฅผ ๊ตฌ์ฑ ์์ ์ธ๋ถ๋ก ์ด๋ํ๊ณ ํ์์ ๋ฐ๋ผ ํธ์ถํ ์ ์๋ค๋ ๊ฒ์
๋๋ค.
static propTypes = {
id: PropTypes.number.isRequired,
email: function(props, propName, componentName) {
const propValue = props[propName] // the actual value of `email` prop
if (propValue === null) return
if (typeof propValue === 'string') return
return new Error(`${componentName} only accepts null or string`)
}
}
๋๋ ์ด ์๋ฃจ์ ์ด PropTypes ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋์์ ๋ฒ์ด๋๋ค๊ณ ์๊ฐํฉ๋๋ค - ๋ด๊ฐ ์ด๊ฒ์ ๋งํ๋ ์ด์ ๋ https://github.com/facebook/prop-types/blob/master/factoryWithTypeCheckers.js์ ์๋ PropTypes ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ์๋ ์ฝ๋ ๋๋ฌธ์ ๋๋ค.
์ค์ ๋ก ์ ํจ์ฑ์ ๊ฒ์ฌํ๊ธฐ ์ ์ ์์ฑ ๊ฐ์ด null
์ด๋ฉด isRequired๋ก ์ค์ ๋ ์์ฑ์ด ์๋์ผ๋ก ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๋น ๋ฅธ ๊ฒ์ฌ๊ฐ ์ํ๋ฉ๋๋ค. ๋ค๋ฅธ ๋ง๋ก ํ๋ฉด ๊ทธ๋ค์ ํ์ ์์ฑ์ด null์ธ ๊ฒ์ด ์๋ชป๋ ๊ฒ์ด๋ผ๊ณ ์๊ฐํ์ง๋ง ๋๋ ํ์ null์ด ์๋ ๊ฒ์ด ์ ํจํ ์ฌ์ฉ ์ฌ๋ก๋ผ๊ณ ์๊ฐํฉ๋๋ค.
if (props[propName] == null) {
if (isRequired) {
if (props[propName] === null) {
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required ' + ('in `' + componentName + '`, but its value is `null`.'));
}
return new PropTypeError('The ' + location + ' `' + propFullName + '` is marked as required in ' + ('`' + componentName + '`, but its value is `undefined`.'));
}
return null;
} else {
return validate(props, propName, componentName, location, propFullName);
}
๋ช
์๋ ์ด์ ๋ก @jharris4 ์ ๋์ํฉ๋๋ค. null
๋ undefined
์ ๋ค๋ฆ
๋๋ค. ์๋ฆฌ ํ์์๋ก ์ฌ์ฉํ๋ ๊ฒ์ด ํ์ค์
๋๋ค.
Mozilla ๊ฐ๋ฐ์ ๋คํธ์ํฌ์์:
null ๊ฐ์ ๊ฐ์ฒด ๊ฐ์ด ์๋์ ์ผ๋ก ์์์ ๋ํ๋ ๋๋ค.
null์ undefined์ ๊ฐ์ด ์ ์ญ ๊ฐ์ฒด์ ์์ฑ์ ๋ํ ์๋ณ์๊ฐ ์๋๋๋ค. ๋์ null์ ์๋ณ ๋ถ์กฑ์ ๋ํ๋ด๋ฉฐ ๋ณ์๊ฐ ๊ฐ์ฒด๋ฅผ ๊ฐ๋ฆฌํค์ง ์์์ ๋ํ๋ ๋๋ค. API์์ null์ ์ข ์ข ๊ฐ์ฒด๊ฐ ์์๋์ง๋ง ๊ด๋ จ ๊ฐ์ฒด๊ฐ ์๋ ์์น์์ ๊ฒ์๋ฉ๋๋ค.
null์ ์ ์ด๋ PropTypes.oneOfType([null, PropTypes.string]).isRequired
ํตํด ํ์ฉ๋์ด์ผ ํฉ๋๋ค.
@jquense โ isRequired
์ ๊ฑฐํ๋ฉด ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํด์ผ ํฉ๋๋ค. ์ด๊ฒ์ null
๋ฅผ ์ํ์ ๊ฐ์ผ๋ก ํ์ฉํ๋ ๊ฒ์ ํผํ๊ธฐ ์ํด ๊ฐ์๊ธฐ์ ๊ตฌ์ฑ ์์ _๋ฐ_์ ์ด๊ธฐ ๊ฐ์ ๋ํ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๊น?
API ํธ์ถ์ ๊ธฐ๋ค๋ฆฌ๋ ๋์ ์ ํ๊ธฐ์ data || ''
( isRequired
๋น ๋ฌธ์์ด ''
, ๋น ๊ฐ์ฒด {}
๋ฑ)์ด ๋ง์ด ์์ต๋๋ค. finish null
๋ ๊ตฌ์ฑ ์์์ ๋ฐ์ดํฐ๊ฐ ์ฌ ๊ฒ์ด๋ผ๊ณ ์๋ ค์ฃผ๋ ์๋ฒฝํ ๋ฐฉ๋ฒ์
๋๋ค. ์ ์๋ง ๊ธฐ๋ค๋ฆฌ์ธ์! (ํ์ง๋ง ๋ ๊ทธ๋ด ์ ์์ด...)
@puiu91 ์ ์ง๊ธ ์ข์ ํด๊ฒฐ ๋ฐฉ๋ฒ์ ๊ฐ์ง๊ณ ์์ต๋๋ค... ์ฝ๋๋ฒ ์ด์ค์์ ์ฌ์ฉํ ์ ํธ๋ฆฌํฐ ํจ์๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค... ์ด ๋ฌธ์ ๊ฐ ๊ณง ๋ค์ ์ด๋ฆฌ์ง ์์ ๊ฒ ๊ฐ๊ธฐ ๋๋ฌธ์ ํ์จ
๋๋ ๋ํ @jharris4 ์ @Findiglay๊ฐ ์ธ๊ธํ ๊ฒ๊ณผ ๊ฐ์ ์ด์ ๋ก null
๋ฅผ ๊ฐ์ผ๋ก ๋ฐ์๋ค์ด๋ ํ์ค ๋ฐฉ๋ฒ์ด ์์ด์ผ ํ๋ค๋ ๋ฐ ๋์ํ์ง๋ง, ์ด๊ฒ์ ๋ ์ด์ ๋
ผ์๋ฅผ ๊ณ์ํ ์ฅ์๊ฐ ์๋๋๋ค. ์ด ๋ฌธ์ ๋ ์ข
๋ฃ๋์์ ๋ฟ๋ง ์๋๋ผ facebook/prop-types ์ ์ํฉ๋๋ค. ์ฌ๊ธฐ facebook/prop-types#90์์ pull ์์ฒญ์ ๋ฐ๋ฅด๊ณ ์์ต๋๋ค.
์ถฉ๋. ์ค๋๋ ์๋ ์ฌ์ ํ ์คํ ์ค์ ๋๋ค. ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ง์ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
myObj: PropType.object.isRequiredOrNull :)
๋๋ ์ด๊ฒ์ ๋ํ ์ฐ์ ์์๊ฐ ๋งค์ฐ ๋ฎ๋ค๊ณ ์๊ฐํฉ๋๋ค. ํ๋ฆ์ ๊ถ์ฅ๋๋ ๋ฐฉ๋ฒ์ ๋๋ค. http://flow.org/
@Marujah ์ค๋ํซ์ด ์ฌ๋ฐ๋ฅด์ง ์์ต๋๋ค.
๊ตฌ์ฑ ์์์ null์ ์ ๋ฌํ๋ฉด ๊ฒฝ๊ณ ๊ฐ ํ์๋ฉ๋๋ค.
Warning: Failed prop type: The prop 'theProp' is marked as required in 'TheComponent', but its value is null.
๋ฌธ์ ๋ isRequired๊ฐ ๋จผ์ ํ๊ฐ๋๊ณ null ๋๋ ์ ์๋์ง ์์ ๊ฐ์ ํต๊ณผ์ํค์ง ์๋๋ค๋ ๊ฒ์ ๋๋ค.
๊ด์ฌ์ด ์๋ ๊ฒฝ์ฐ ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํ prop-types์ ๋ํ PR์ด ์์ ๋งํฌ๋์ด ์์ต๋๋ค.
์ ์ ๋ง! ๋ค์ ํ ๋ฒ ๋น์ ์ด ์ณ๋ค
๊ฐ ๋๋ null์ด ๊ตฌ์ฒด์ ์ผ๋ก ์ ๊ณต๋์ด์ผ ํ๋ค๋ ์๊ตฌ๋ PropTypes๋ฅผ ํตํด ์ ๋์ ์ผ๋ก ํ์ฉ๋์ด์ผ ํฉ๋๋ค.
๋ค์์ ๋ด๊ฐ ๊ฒช๊ณ ์๋ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. ์ ํ์์ 90%๊ฐ ํ์๋ก ํ๋ ๋ช ๊ฐ์ง ์ฝ๋ฐฑ์ด ์์ต๋๋ค. ๊ทธ๊ฒ๋ค์ด ํ์ํ์ง ์์ ์์๋ ๋งค์ฐ ๊ตฌ์ฒด์ ์ธ ์ฌ์ฉ ์ฌ๋ก์ ๋๋ค. ์ผ๋ฐ์ ์ธ ์ฝ๋ฐฑ์ ๋ชจ๋ ์ ๊ณตํ๋ ๊ฒ์ ์ง์์ ์ผ๋ก ์์ด๋ฒ๋ฆฌ๋ ์๋ก์ด ๊ฐ๋ฐ์๊ฐ ์์ต๋๋ค.
์ด ๊ตฌ์ฑ ์์์ ๋ชจ๋ ์ฌ์ฉ์ด ํน์ ์ฝ๋ฐฑ์ ํฌํจํ์ง ์๋๋ก ์์์ ์ธ ๊ฒฐ์ ์ ๋ด๋ฆฌ๋๋ก ๊ฐ์ ํ๊ณ ์ถ์ต๋๋ค. ๋๊ตฐ๊ฐ๊ฐ ๋ช ๊ฐ์ง ์ํ์ ์์ด๋ฒ๋ฆฌ๋ ๊ฒ์ด ์๋๋ผ.
์, ํ๋ฆ์ ํตํด ๋ณด๋ค ๊ตฌ์ฒด์ ์ธ ๊ฒ์ฌ๋ฅผ ํดํนํ ์ ์์ง๋ง ์ด๋ props ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๋ ๊ณณ์ผ๋ก ๋ถํ ํ๊ณ propTypes ์ ์๋ฅผ ์ดํด๋ณด๋ ์ฌ๋์๊ฒ๋ ๋ค์ ์ง๊ด์ ์ด์ง ์์ต๋๋ค.
์ฌ๊ธฐ์ ๋ด ์ฌ์ฉ ์ฌ๋ก๋ฅผ ์ถ๊ฐํ๊ณ ์ถ์์ต๋๋ค. ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์จ ์๊ฐ๊ณผ ํจ๊ป ๋ฐ์ดํฐ๊ฐ ์๋ redux ์ ์ฅ์๊ฐ ์์ต๋๋ค. ์ค๋ฅ๊ฐ ์๋ ๊ฒฝ์ฐ ๋ฑ์ด ์์ต๋๋ค. ๋ด ๊ตฌ์ฑ ์์์๋ '์ค๋ฅ' ์ํ์ด ํ์ํฉ๋๋ค(๋ฐ๋ผ์ ๋ฐ์ดํฐ๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ ๊ฒฝ์ฐ ์ฌ์ฉ์์๊ฒ ์ค๋ฅ๋ฅผ ํ์ํ ์ ์์). ๋ฐ์ดํฐ๊ฐ ์ฑ๊ณต์ ์ผ๋ก ๋ก๋๋๋ฉด null์ด์ง๋ง ์ค๋ฅ๊ฐ ์์ผ๋ฉด ์ฑ์์ง๋๋ค.
๋ก๋ ๊ตฌ์ฑ ์์( PropTypes.node
)๋ฅผ props
์ ๋ฌํ๊ณ ๋ก๋๋ฅผ ๋ ๋๋งํ์ง ์์ผ๋ ค๋ฉด null
ํฉ๋๋ค.
Afaik, render
ํจ์๋ ์๋ฌด ๊ฒ๋ ๋ ๋๋งํ์ง ์์ ๋ undefined
๋์ null
๋ฅผ ๋ฐํํด์ผ ํฉ๋๋ค. ๋ฐ๋ผ์ null
๋ฅผ ๊ฐ์ผ๋ก ์ ๋ฌํ๋ ๊ฒ์ด ์ฌ๋ฐ๋ฅธ ๋ฐฉ๋ฒ์ผ๋ก ๋ณด์
๋๋ค.
๋ด๊ฐ InputNumber ๊ตฌ์ฑ ์์๋ฅผ ๊ตฌํํ๋ค (๋ํผ <input type="number">
), ๋ด๊ฐ ๊ฐ์ง ๊ทธ๋์ propTypes
๋ด ์ํ์ ๋ํ value
- PropTypes.number.isRequired
, ๊ทธ๋ฆฌ๊ณ ๋ด ๊ตฌ์ฑ ์์, I๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ํญ์ ์์ฑ์ ์ ๋ฌํ์ต๋๋ค. ํ์ง๋ง ์ค๋์ ๊ธฐ๋ณธ์ ์ผ๋ก ๊ฐ์ ๋ํ ๋งํฌ๋ฅผ nullable๋ก ์ ๋ฌํด์ผ ํ๋ฉฐ ๊ตฌ์ฑ ์์๊ฐ ๊ฒฝ๊ณ ๋ฅผ ์ถ๊ฐํฉ๋๋ค. ๋ด๊ฐ ์์ํ ์ ์๋ ์ ์ผํ ๊ฒฐ์ ์ propTypes
๋ํ value
๋ฅผ PropTypes.oneOfType([PropTypes.number, PropTypes.string])
ํ๊ณ defaultProps
๋ฅผ null๋ก ์ค์ ํ๋ ๊ฒ์
๋๋ค. ๊ทธ๋ฌ๋ input type=number๋ ์ซ์๋ก๋ง ์๋ํด์ผ ํ๊ธฐ ๋๋ฌธ์ ์ฌ๋ฐ๋ฅธ ๊ฒ์ด ์๋๋ผ๊ณ ์๊ฐํฉ๋๋ค.
๋๋
PropTypes.oneOfType([null, PropTypes.object]).isRequired
์๋ํ๊ณ ์์ผ๋ฏ๋ก null ๋๋ ๊ฐ์ฒด ์ค ํ๋๊ฐ ํ์ฌ ๊ฐ๋ฅํ์ง ์์ต๋๊น?
Warning: Invalid argument supplied to oneOfType. Expected an array of check functions, but received null at index 1.
ํจ์๊ฐ ํ์ํฉ๋๋ค.
๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
PropTypes.oneOfType([
() => null,
PropTypes.object
]).isRequired
๋ฐฉ๊ธ ์ด ๋ฒ๊ทธ๊ฐ ๋ฐ์ํ์ฌ ์ด๋ฅผ ํด๊ฒฐํ๊ธฐ ์ํด ํธ์ ๊ธฐ๋ฅ์ ์์ฑํ์ต๋๋ค.
function nullable(subRequirement) {
const check = (required, props, key, ...rest) => {
if (props[key] === null) {
return null;
}
const sub = required ? subRequirement.isRequired : subRequirement;
return sub(props, key, ...rest);
};
const fn = check.bind(null, false);
fn.isRequired = check.bind(null, true);
return fn;
}
์ฉ๋ฒ:
static propTypes = {
someCallbackFunction: nullable(PropTypes.func).isRequired,
};
nullable
์์ด isRequired
nullable
๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ๊ฐ๋ฅํฉ๋๋ค(๊ทธ๋ฌ๋ ์คํ๋ ค ๋ฌด์๋ฏธํฉ๋๋ค). isRequired
์ ํธํ๋๋๋ก ๋ง๋ ์ด์ ๋ react/require-default-props
eslint ๊ท์น๊ณผ ํจ๊ป ์๋ํ๊ธฐ ์ํจ์
๋๋ค.
๋ด ์ฌ์ฉ ์ฌ๋ก๋ ์ฝ๋ฐฑ์ ์ฒ๋ฆฌํ๋ ๋จ์ผ ๊ตฌ์ฑ ์์๋ก ๋ํ๋ ๊ณตํต API๋ฅผ ์ค์ํ๋ ์ผ๋ จ์ ๊ตฌ์ฑ ์์์
๋๋ค. null
์ฝ๋ฐฑ์ '์ฝ๊ธฐ ์ ์ฉ'์ ์๋ฏธํ๋ฏ๋ก ๋ํผ ๊ตฌ์ฑ ์์๋ ๋๋๋ก ์๋์ ์ผ๋ก null
ํฉ๋๋ค. ๋์์ ์ ์์ฑ์ด ์ถ๊ฐ๋ ๋ ๋๋ฝ๋์ง ์๋๋ก ๋ชจ๋ ์์ฑ์ ํ์ ๊ตฌ์ฑ ์์์ ์ ๋ฌํ๋ ๊ฒ์ด ์ค์ํฉ๋๋ค. ๋ํ ์ด API๋ฅผ ์ค์ํ๋ ๋ชจ๋ ๊ตฌ์ฑ ์์์ ๋ํด defaultProps
null์ ์ ๊ณตํ๊ณ ์ถ์ง ์์ต๋๋ค. ๊ทธ๋ค์ด ์๊ณ ์๋ ํ ํธ์ถ์๋ ๊ฐ์ ์ง์ ํด์ผ ํฉ๋๋ค.
๋๋ ์ ์ ์์ฑํ ๋์ฐ๋ฏธ๋ฅผ ๊ฐ์ ธ ์์ ์ ํ์ฑ์ ์ฆ๋ช ํ๊ธฐ ์ํด ๋ง์ ํ ์คํธ์ ํจ๊ป ํจํค์ง์ ๋ฃ์์ต๋๋ค.
npm install --save git+https://github.com/davidje13/prop-types-nullable.git#semver:^1.0.0
์ฉ๋ฒ:
import PropTypes from 'prop-types';
import nullable from 'prop-types-nullable';
[...]
static propTypes = {
thing: nullable(PropTypes.string).isRequired,
};
์๋ก์ด ์๋ฃจ์
: PropTypes.oneOfType([PropTypes.object]).isRequired
์ค๋ฅ๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๋ป๊ฒ ๊ณ ์น๋ ์ง.
./~/prop-types/prop-types.js์ ๊ฒฝ๊ณ ์ค์ํ ์ข ์์ฑ: 1:482-489 ์ด๊ฒ์ ๋ฏธ๋ฆฌ ๋น๋๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ์ธ ๊ฒ ๊ฐ์ต๋๋ค. ๊ฐ๋ฅํ์ง๋ง ๊ถ์ฅ๋์ง๋ ์์ต๋๋ค. ๋ ๋์ ๊ฒฐ๊ณผ๋ฅผ ์ป์ผ๋ ค๋ฉด ์๋ณธ ์์ค๋ฅผ ์๊ตฌํ์ญ์์ค. @ ./~/prop-types/prop-types.js 1:482-489
๋๋
PropTypes.oneOfType([null, PropTypes.object]).isRequired
์๋ํ๊ณ ์์ผ๋ฏ๋ก null ๋๋ ๊ฐ์ฒด ์ค ํ๋๊ฐ ํ์ฌ ๊ฐ๋ฅํ์ง ์์ต๋๊น?
Warning: Invalid argument supplied to oneOfType. Expected an array of check functions, but received null at index 1.
ํจ์๊ฐ ํ์ํฉ๋๋ค.๋ฐ๋ผ์ ๋ค์๊ณผ ๊ฐ์ ๊ธฐ๋ฅ์ ์ ๊ณตํด์ผ ํฉ๋๋ค.
PropTypes.oneOfType([ () => null, PropTypes.object ]).isRequired
์ฌ์ค ๋ง์ง๋ง์ 'isRequired'๋ผ๋ ์ค๋ฅ ๋๋ฌธ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ฐ, null์ธ ๋์์ ํ์๋ ํธํ๋์ง ์์ต๋๋ค...
์ด๊ฒ์ด ๋๋ฅผ ์ํด ์ผํ ๊ฒ์
๋๋ค.
PropTypes.oneOfType([
PropTypes.string.isRequired,
() => null
])
@ gugol2 ๊ทธ๋ฅ ๋นํ์ฑํ ํ์
์ด ์์ ํ ํ์ธํฉ๋๋ค ์์ฑํ ๊ฒ์์ฃผ์ํ์ญ์์ค (๋น์ ์ด ์ง๊ธ ์ํ์ ๋ฒํธ๋ฅผ ํต๊ณผ, ๋๋ ์ undefined
, ๋๋ ์๋ฌด๊ฒ๋); ๊ทํ๊ฐ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ๋ฐํํด์ผํฉ๋๋ค null
๊ฒ์ฆ์ด ์ฑ๊ณตํ๊ณ ์๋ ๊ฒฝ์ฐ ๋น null
์คํจํฉ๋๋ค.
ํด๋น ๊ฒฝ๋ก๋ก ์ด๋ํ๋ ค๋ฉด ๋ค์๊ณผ ๊ฐ์ ๊ฒ์ด ๋ ํ์ํฉ๋๋ค.
PropTypes.oneOfType([
PropTypes.string.isRequired,
(props, key) => props[key] === null ? null : 'Not null'
])
๋ฌผ๋ก ๋ณด๊ธฐ ํํ ๋์ฐ๋ฏธ ํจ์๋ฅผ ๋ฏธ๋ฆฌ ์ ์ํ ์ ์์ต๋๋ค.
const nullable = (props, key) => props[key] === null ? null : 'Not null'
// ...
PropTypes.oneOfType([PropTypes.string.isRequired, nullable])
PropTypes.oneOfType([PropTypes.string.isRequired])
์ฌ์ฉํ๋ ๊ฒ๋ ๊ธฐ์ดํ๊ฒ๋ ๊ฐ๋ฅํฉ๋๋ค(ํ์ง๋ง ์ ๋ง ์ถ์ฒํ์ง ์์ต๋๋ค!). ์ด๊ฒ์ ๋ฒ๊ทธ์ฒ๋ผ ๋๊ปด์ง๋ฉฐ ๊ทธ๋ฐ ์ฝ๋๊ฐ ์ดํ ๋ฒ์ ์์ ์ด์๋จ์ ๊ฒ์ด๋ผ๊ณ ๊ธฐ๋ํ์ง ์์ต๋๋ค. ๋ํ ์๋ํ์ง ์๋ ์ด์ ์ ์ ์๋ ๋ฐฉ๋ฒ ๊ณผ ์ ์ฌํ์ง๋ง ๋์ผํ์ง๋ ์์ต๋๋ค.
๊ธฐ๋ค๋ฆด ์ ์๋ค๋ฉด ๋ฏฟ์ ์ ์์ ์ ๋๋ก ๋๋ฆฌ๊ฒ ์์ง์ด์ง๋ง ๋ถ๋ช ํ ์ฌ์ ํ ๊ณ ๋ ค ์ค์ธ ๊ณต๊ฐ PR ์ด ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ PR์ด ๋ณํฉ๋ ๋๊น์ง ๋ด๊ฐ ๋ง๋ ํจํค์ง (๋๋ ๊ทธ ๋ค์ ์๋ .isRequired
๋ฅผ ์ถ๊ฐํ์ฌ Linting ๊ท์น๊ณผ ํธํ๋๊ธฐ ๋๋ฌธ์
๋๋ค.
IMHO ์ด๊ฒ์ ์ฌ๋ฐ๋ฅธ ๋์์ด์ง๋ง ๋ฌธ์ํํด์ผ ํฉ๋๋ค.
๋ด๊ฐ ๋ณด๋ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ ๋ฐ์ดํฐ์ ๋ํ API ํธ์ถ์ด ์๋ฃ๋๊ธฐ ์ ์ ๊ตฌ์ฑ ์์๋ฅผ ๋ ๋๋งํ๋ React์ ๋๋ค. ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์ ์๋ฅผ ๋ค์ด ํญ๋ชฉ ๋ชฉ๋ก(
items: null
)์ ๋ ๋๋งํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ API ํธ์ถ์ด ์๋ฃ๋๊ณ ์ด์ items
๊ฐ ๋ฐฐ์ด๋ก ์ฑ์์ง๋๋ค.
์ด๊ฒ์ ์ฒ๋ฆฌํ๋ ๊ฐ์ฅ ์ข์ ๋ฐฉ๋ฒ์ ๋ฌด์์ ๋๊น? ์ด ์ํ์ด ํ์ํ์ง๋ง API์์ ๋ค์ ๊ฐ์ ธ์ค๊ธฐ ์ ์ null์ ๋๋ค.
PropTypes.oneOfType([ PropTypes.string.isRequired, (props, key) => props[key] === null ? null : 'Not null' ])
@ davidje13 ์ด ์ ๊ทผ ๋ฐฉ์์ ์ฝ๊ฐ์ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์ ์ฉ ๋ฒ์ ํ ์คํธ์๋ ์ ์ฉ๋์ง ์๋ 1/4 ์ผ์ด์ค๊ฐ ์์ต๋๋ค.
null ๋๋ ๋ฌธ์์ด์ด ํ์ํ ์ ์๋ ํ๋์ prop 'name'๋ง ์๋ ๋ก๊ทธ์ธ ๊ตฌ์ฑ ์์๊ฐ ์๋ค๊ณ ๊ฐ์ ํด ๋ณด๊ฒ ์ต๋๋ค.
const Login = ({name}) => {
return <div>{name}</div>
}
๋ฐ๋ผ์ ๊ทธ proptypes๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
Login.propTypes = {
name: PropTypes.oneOfType([
PropTypes.string.isRequired,
(props, key) => (props[key] === null ? null : 'Not null'),
]),
};
์ด ๊ตฌ์ฑ ์์๋ฅผ ํ ์คํธํ ๋ null ๋๋ ํ์ ๋ฌธ์์ด์ 2๊ฐ์ง ์๋๋ฆฌ์ค๋ง ์์ต๋๋ค.
render(<Login name={null} />
render(<Login name={'anyName'} />
๊ทธ๋ฌ๋ ์ ์ฉ ๋ฒ์์ ๋ฐ๋ฅด๋ฉด ๋ด ํ
์คํธ์๋ 75%๋ง ์ ์ฉ๋ฉ๋๋ค.
์ด์ ๋ํ ๊ณต์์ ์ธ ์ ๊ทผ์ ์ด๋ป๊ฒ ๋๋์ง ๊ถ๊ธํฉ๋๋ค.
๋๋ฝ๋ ํ ์คํธ ์ผ์ด์ค๊ฐ ์ํ ๊ฒ์ฌ์ ์คํจํ ๊ฒ ๊ฐ์ต๋๊น? ์ฆ, ์ซ์๋ ์ ์๋์ง ์์ ๊ฒ์ ์ ๋ฌํ๋ฉด ์ ๋๋ ๊ฒ์ ๋๋ค.
๋๋ฝ๋ ํ ์คํธ ์ผ์ด์ค๊ฐ ์ํ ๊ฒ์ฌ์ ์คํจํ ๊ฒ ๊ฐ์ต๋๊น? ์ฆ, ์ซ์๋ ์ ์๋์ง ์์ ๊ฒ์ ์ ๋ฌํ๋ฉด ์ ๋๋ ๊ฒ์ ๋๋ค.
์๋, ๊ทธ๊ฒ ์๋์ผ.
undefined๋ฅผ ์ ๋ฌํด๋ ์ ์ฉ ๋ฒ์๊ฐ ํ์ฅ๋์ง ์์ต๋๋ค.
๊ทธ๋ฆฌ๊ณ ์ด์จ๋ ์ซ์๋ฅผ ์ ๋ฌํ ์ ์์ต๋๋ค. ํ์ฉ๋๋ ๊ฐ์ด ์๋๋๋ค.
๋๋ ๊ทธ ์ฌ๊ฑด์ ๋ฎ์ ์ ์๋ค.
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
๋ด๊ฐ ๋ณด๋ ์ผ๋ฐ์ ์ธ ์ฌ์ฉ ์ฌ๋ก๋ ๋ฐ์ดํฐ์ ๋ํ API ํธ์ถ์ด ์๋ฃ๋๊ธฐ ์ ์ ๊ตฌ์ฑ ์์๋ฅผ ๋ ๋๋งํ๋ React์ ๋๋ค. ์ฒซ ๋ฒ์งธ ๋ ๋๋ง์ ์๋ฅผ ๋ค์ด ํญ๋ชฉ ๋ชฉ๋ก(
items: null
)์ ๋ ๋๋งํฉ๋๋ค. ๊ทธ๋ฐ ๋ค์ API ํธ์ถ์ด ์๋ฃ๋๊ณ ์ด์ items
๊ฐ ๋ฐฐ์ด๋ก ์ฑ์์ง๋๋ค.