Definitelytyped: React.Children.map () рдФрд░ React.cloneElement () рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ

рдХреЛ рдирд┐рд░реНрдорд┐рдд 26 рдЕрдХреНрддреВре░ 2016  ┬╖  8рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ  ┬╖  рд╕реНрд░реЛрдд: DefinitelyTyped/DefinitelyTyped

React.Children.map() рдореЗрдВ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрджрд╛рд╣рд░рдг рдирд╣реАрдВ рд╣реИ , рдореБрдЭреЗ рд╕рдордЭ рдирд╣реАрдВ рдЖ рд░рд╣рд╛ рд╣реИ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдЯрд╛рдЗрдк рдХрд┐рдпрд╛ рдЬрд╛рдП:

/*
<CheckboxGroup ...>
  <Checkbox ... />
  <Checkbox ... />
  <Checkbox ... />
</CheckboxGroup>
*/

// Child
class Checkbox extends React.Component<CheckboxProps, void> {
  // ...
}

// Parent
class CheckboxGroup extends React.Component<CheckboxGroupProps, void> {
  // ...

  render() {
    const checkboxes = React.Children.map(this.props.children, checkbox =>
      React.cloneElement(checkbox, {
        name: this.props.name,
        checked: this.props.checkedValues.includes(checkbox.props.value),
        onChange: this.handleCheckboxChange.bind(this)
      })
    );

    return (
      <div>
        {checkboxes}
      </div>
    );
  }
}

(рдмрд╣реБрдд рд╣реА рд╕рд╛рдорд╛рдиреНрдп рдЙрджрд╛рд╣рд░рдг, http://stackoverflow.com/a/32371612/990356 рджреЗрдЦреЗрдВ)

  • this.props.children рдХреИрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВ?
  • React.cloneElement() рдХреИрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВ?
  • React.Children.map() рдХреИрд╕реЗ рдЯрд╛рдЗрдк рдХрд░реЗрдВ?

рдЕрдзрд┐рдХрд╛рдВрд╢ рд╕рдордп рдореИрдВ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддреНрд░реБрдЯрд┐ рдХреЗ рд╕рд╛рде рд╕рдорд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реВрдВ: Type 'string' is not assignable to type 'ReactElement<any>' , рджреЗрдЦреЗрдВ #8131

рд╕рдмрд╕реЗ рдЙрдкрдпреЛрдЧреА рдЯрд┐рдкреНрдкрдгреА

рдкреНрд░рд╢реНрди:

const checkboxes = React.Children.map(this.props.children, checkbox =>
  React.cloneElement(checkbox, {
    name: this.props.name,
    checked: this.props.checkedValues.includes(checkbox.props.value),
    onChange: this.handleCheckboxChange.bind(this)
  })
);

рд╕рдорд╛рдзрд╛рди:

const checkboxes = React.Children.map(props.children, (checkbox: React.ReactElement<CheckboxPropsInternal>) =>
  React.cloneElement(checkbox, {
    checked: props.checkedValues.includes(checkbox.props.value),
    onChange: handleCheckboxChange
  })
);

рд╕рднреА 8 рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

рдХреГрдкрдпрд╛ рдПрдХ рдкреБрд▓ рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдВред рдореИрдВ рдЗрд╕рдХреА рд╕рдореАрдХреНрд╖рд╛ рдХрд░реВрдВрдЧрд╛ред

@vvakame рдореИрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддрд╛, рдореБрдЭреЗ рд╕рдордЭ рдореЗрдВ рдирд╣реАрдВ рдЖрддрд╛ рдХрд┐ рдЗрд╕реЗ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП

рдореИрдВ рднреАред рдХреГрдкрдпрд╛ рдкрд░рд┐рднрд╛рд╖рд╛ рд▓реЗрдЦрдХреЛрдВ рдХреЗ рд╕рд╛рде рдмрд╛рддрдЪреАрдд рдХрд░реЗрдВред

рдЖрдкрдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ checkbox рдЯрд╛рдЗрдк-рдПрдиреЛрдЯреЗрдЯ рдпрд╛ рдЯрд╛рдЗрдк-рдПрд╕рд░реНрдЯ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрдЧреА рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ this.props.children рдореЗрдВ рдЧреИрд░-ReactElement рдорд╛рди рд╢рд╛рдорд┐рд▓ рдирд╣реАрдВ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:

React.Children.map(this.props.children, (checkbox: React.ReactElement<CheckboxProps>) => 
    React.cloneElement(checkbox) // should be ok
);

@vsiao thx рдмрд╣реБрдд, рдпрд╣ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИ!

рдкреНрд░рд╢реНрди:

const checkboxes = React.Children.map(this.props.children, checkbox =>
  React.cloneElement(checkbox, {
    name: this.props.name,
    checked: this.props.checkedValues.includes(checkbox.props.value),
    onChange: this.handleCheckboxChange.bind(this)
  })
);

рд╕рдорд╛рдзрд╛рди:

const checkboxes = React.Children.map(props.children, (checkbox: React.ReactElement<CheckboxPropsInternal>) =>
  React.cloneElement(checkbox, {
    checked: props.checkedValues.includes(checkbox.props.value),
    onChange: handleCheckboxChange
  })
);

@tkrotoff рдЖрдк рдпрд╣ рднреА рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:

    React.Children.map(this.props.children, (child: number) => {
      return child + 1
    })

рдпрд╣ рдФрд░ рд╕реБрдЭрд╛рдП рдЧрдП рд╕рдорд╛рдзрд╛рди рдХреЗрд╡рд▓ рдЗрд╕ рддрдереНрдп рдХрд╛ рд▓рд╛рдн рдЙрдард╛ рд░рд╣реЗ рд╣реИрдВ рдХрд┐ React.Children.map рджреГрдврд╝рддрд╛ рд╕реЗ рдЯрд╛рдЗрдк рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЖрдкрдиреЗ Checkbox рдкреНрд░рдХрд╛рд░ рдХреЗ рдмрдЬрд╛рдп any рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реЛрдЧрд╛ рдХреНрдпреЛрдВрдХрд┐ рдЗрд╕ рдмрд╛рдд рдХреА рдХреЛрдИ рдЧрд╛рд░рдВрдЯреА рдирд╣реАрдВ рд╣реИ рдХрд┐ рдпрд╣ рдмрдЪреНрдЪреЛрдВ рдХрд╛ рдкреНрд░рдХрд╛рд░ рд╣реЛрдЧрд╛ред рдЗрд╕рдХрд╛ рдорддрд▓рдм рдпрд╣ рд╣реИ рдХрд┐ рдпрджрд┐ рдХреЛрдИ рд╕реНрдЯреНрд░рд┐рдВрдЧ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдХреЗ рдШрдЯрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рд╕реЗ рдЪреВрдХ рдЬрд╛рддрд╛ рд╣реИ рддреЛ рдЖрдкрдХреЛ рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐рдпрд╛рдВ рд╣реЛрдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рд╣реИред

рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рдХреИрд╕рд╛ рд╣реИ:

class Slot extends React.PureComponent {
  render () {
    return this.props.children
  }
}

const isReactElement = (obj: {}): obj is React.ReactElement<{}> => {
  return obj.hasOwnProperty('type')
}

const isSlot = (obj: {}): obj is Slot => {
  return isReactElement(obj) && obj.type === Slot
}

const getSlots = (children: React.ReactNode) => React.Children.map(children, (child: React.ReactChild): JSX.Element | null => {
  if (isReactElement(child) && isSlot(child)) {
    return child
  }

  return null
})

class ComponentWithSlots extends React.PureComponent {
  render () {
    const [header, footer] = getSlots(this.props.children)

    return (
      <div>
        {header}
        <div>
          <h1>Welcome</h1>
          <p>This is my lovely component with slots</p>
        </div>
        {footer}
      </div>
    )
  }
}

class MyComponent extends React.PureComponent {
  render () {
    return (
      <ComponentWithSlots>
        <Slot>My Header!</Slot>
        <Slot>
          <div>github: @variousauthors</div>
        </Slot>
      </ComponentWithSlots>
    )
  }
}

рдЬреЛ рдкреНрд░рд╕реНрддреБрдд рдХрд░реЗрдЧрд╛:

My Header!
Welcome
This is my lovely component with slots

github: <strong i="17">@variousauthors</strong>

рдпрд╣ рджреГрд╖реНрдЯрд┐рдХреЛрдг рд╣рдорд╛рд░реЗ рдкрд╛рд╕ _do_ рдкреНрд░рдХрд╛рд░ рдХреА рдЬрд╛рдирдХрд╛рд░реА рдХрд╛ рд▓рд╛рдн рдЙрдард╛рддрд╛ рд╣реИ, рдЬреЛ рдпрд╣ рд╣реИ рдХрд┐ ReactChild рдПрдХ ReactElement рд╣реЛ рд╕рдХрддрд╛ рд╣реИ (рдореИрдВрдиреЗ рдЗрд╕рдХрд╛ рдкрддрд╛ рд▓рдЧрд╛рдиреЗ рдХреЗ рд▓рд┐рдП type рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЖрдк рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдЕрдзрд┐рдХ рд╕рд╛рд╡рдзрд╛рди рдпрджрд┐ рдЖрдк рдЪрд╛рд╣рддреЗ рдереЗ)ред рд╣рдо рдЕрдзрд┐рдХ рд╡рд░реНрдгрдирд╛рддреНрдордХ рдФрд░ рд╡рд┐рд╕реНрддреГрдд рднреА рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВ рдХрд┐ Slot ред рдореИрдВрдиреЗ рджреЗрдЦрд╛ рдХрд┐ рдПрдХ UI рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдПрдХ рдкреИрдЯрд░реНрди рдХреЛ рд▓рд╛рдЧреВ рдХрд░рддреА рд╣реИ рдЬрд╣рд╛рдБ рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рдЕрдкрдиреЗ рд╕реНрд▓реЙрдЯ рд╕рдВрд▓рдЧреНрди рд╣реЛрддреЗ рд╣реИрдВред рдХреБрдЫ рдЗрд╕ рддрд░рд╣:

<Dropdown>
  <Dropdown.Header>
    <FancyIcon>My Header!</FancyIcon>
  </Dropdown.Header>
  {dropdownItems}
</Dropdown>

рдЗрд╕ рддрд░рд╣ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкреНрд░рддреНрдпреЗрдХ рд╕реНрд▓реЙрдЯ рдХреЗ рдЕрд░реНрде рдкрд░ рд╕реНрдкрд╖реНрдЯ рд╣реИред рд╢реЗрд╖ рдмрдЪреНрдЪреЛрдВ (рдЬрд┐рдиреНрд╣реЗрдВ рд╕реНрд▓реЙрдЯ рдХреЗ рд░реВрдк рдореЗрдВ рдкрд╛рд░реНрд╕ рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ) рдХреЛ children рдирд╛рдордХ рд╕рдВрдЧреНрд░рд╣ рдореЗрдВ рдЫреЛрдбрд╝ рджрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ рдФрд░ рдПрдХ рд▓рд╛ рдХрд╛рд░реНрдЯ рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЕрднреА рднреА children рд╕рд╛рдорд╛рдиреНрдп рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрдмрдХрд┐ рд╡рд┐рд╢реЗрд╖ рд╡реНрдпрд╡рд╣рд╛рд░ рдХреЛ рдЖрд░рдХреНрд╖рд┐рдд рдХрд░рддреЗ рд╣реБрдП рдХрд╕реНрдЯрдо рд╕реНрд▓реЙрдЯред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдореЗрдВ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рд╡рд┐рдзрд┐ рд╣реИ React.isValidElement рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЖрдк рдореЗрд░реЗ рдХрд╕реНрдЯрдо isReactElement рд╕реНрдерд╛рди рдкрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред

рд╕рдВрдкрд╛рджрд┐рдд рдХрд░реЗрдВ: рдХреБрдЫ рдФрд░ рдЬреЛ рдЖрдк рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рд╡рд╣ рд╣реИ рдЕрдкрдиреЗ рдШрдЯрдХ рдкрд░ children рд╕рдВрдкрддреНрддрд┐ рдЯрд╛рдЗрдк рдХрд░реЗрдВ, рддрд╛рдХрд┐ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдХреЗрд╡рд▓ рдмрдЪреНрдЪреЛрдВ рдХреЗ рд░реВрдк рдореЗрдВ рдЪреЗрдХрдмреЙрдХреНрд╕ рдореЗрдВ рдкрд╛рд╕ рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рд╣реЛред рдпрд╣ рдЙрди рд░рдирдЯрд╛рдЗрдо рддреНрд░реБрдЯрд┐рдпреЛрдВ рд╕реЗ рдмрдЪрдиреЗ рдореЗрдВ рдорджрдж рдХрд░реЗрдЧрд╛ред

рдХреНрдпрд╛ рдпрд╣ рдкреГрд╖реНрда рдЙрдкрдпреЛрдЧреА рдерд╛?
0 / 5 - 0 рд░реЗрдЯрд┐рдВрдЧреНрд╕

рд╕рдВрдмрдВрдзрд┐рдд рдореБрджреНрджреЛрдВ

jrmcdona picture jrmcdona  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

JudeAlquiza picture JudeAlquiza  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

victor-guoyu picture victor-guoyu  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

Zzzen picture Zzzen  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ

lilling picture lilling  ┬╖  3рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ