Изменить опору для стилизованного компонента и обновить внешний вид - PullRequest
0 голосов
/ 03 мая 2019

Я очень новичок в стилизованных компонентах (и я не очень хорош в React в целом), и я не могу разобраться с ними. Я создал базовый пример, который представляет собой абстракцию того, чего я хочу достичь. Когда я нажимаю на поле, я хочу, чтобы свойство on было изменено на true, а цвет <Box> был изменен на зеленый в соответствии с правилом background-color.

Как мне этого добиться? Особенно в том случае, когда может быть неопределенное количество ящиков?

Компонент

import React from 'react';
import PropTypes from 'prop-types';
import styled from 'styled-components';

const Box = styled.a`  
    display: block;
    height: 100px;
    width: 100px;
    background-color: ${props => props.on ? 'green' : 'red' };
`;

Box.propTypes = {
    on: PropTypes.bool,
    onClick: PropTypes.func,
}

Box.defaultProps = {
    on: false,
    onClick: () => {},
}

export default Box;

Осуществление

<Box on={ false } onClick={ }></Box>

Ответы [ 2 ]

0 голосов
/ 03 мая 2019

// App.js

import React from "react";
import ReactDOM from "react-dom";
import Test from "./Test";

class App extends React.Component {
  state = {
    on: false
  };
  handleChange = () => {
    this.setState(prevState => ({ on: !prevState.on }));
  };
  render() {
    return (
      <div className="App">
        <Test on={this.state.on} onClick={this.handleChange}>
          Hey
        </Test>
      </div>
    );
  }
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

// Test.js

import PropTypes from "prop-types";
import styled from "styled-components";

const Box = styled.a`
  display: block;
  height: 100px;
  width: 100px;
  background-color: ${props => (props.on ? "green" : "red")};
`;

Box.propTypes = {
  on: PropTypes.bool,
  onClick: PropTypes.func
};

Box.defaultProps = {
  on: false,
  onClick: () => {}
};

export default Box;
0 голосов
/ 03 мая 2019

Вы бы обработали состояние в его родительском компоненте.Например, вы можете сделать что-то вроде этого:

class Page extends Component {
  state = { on: false }

  handleClick = () => {
    this.setState(prevState => ({ on: !prevState.on }));
  }

  render() {
    return <Box on={this.state.on} onClick={this.handleClick} />
  }
}

Или еще проще, используя ловушки React:

const Page = () => {
  const [on, setOn] = useState(false);
  return <Box on={on} onClick={() => setOn(on => !on)} />;
};

Вот пример того, что вы могли бы сделать, если вы хотели 10 коробок

(примечание: создание обработчика onClick в методе рендеринга, как я сделал, может привести к проблемам с производительностью, если у вас очень большое количество блоков)

class Page extends Component {
  state = { boxes: Array(10).fill(false) }

  handleClick = (index) => {
    this.setState(prevState => ({
      boxes: [
        ...prevState.boxes.slice(0, index),
        !prevState.boxes[index],
        ...prevState.boxes.slice(index)
      ]
    }));
  }

  render() {
    return (
      <React.Fragment>
        {this.state.boxes.map((on, index) =>
          <Box on={on} onClick={() => this.handleClick(index)} />
        )}
      </React.Fragment>
    );
  }
}
...