I am trying to use Radium in react

716 views Asked by At

So I have two components, Person and App, the person component has some inline CSS styling that I was to use with react, but I am getting the following error.

Module '"../../../../../../Users/7oss/Desktop/ReactTutorials/my-first-portfolio/node_modules/@types/radium"' has no exported member 'StyleRoot'.ts(2305)

I am trying to add @media styling to the Person Component.

I have tried doing Radium.StyleRoot instead of StyleRoot, but I got the following error:

Objects are not valid as a React child (found: object with keys {@media (min-width: 500px)}). If you meant to render a collection of children, use an array instead.

Here is the App Component:

 import React, { Component, ChangeEvent } from "react";
import "./App.css";
import Person from "./Components/Person/Person";
import Radium, { StyleRoot } from "radium";

class App extends Component {
  state = {
    persons: [
      { id: "hoba", name: "Hosam", age: 24 },
      { id: "hoba1", name: "Ayah", age: 18 },
      { id: "hoba2", name: "Test", age: 20 }
    ],
    ShowPersons: false
  };

  deletePersonHandler = (personIndex: any) => {
    // const persons = this.state.persons.slice(); this is one way
    const persons = [...this.state.persons]; // Another way
    persons.splice(personIndex, 1);
    this.setState({ persons: persons });
  };

  nameChangeHandler = (event: any, id: any) => {
    // console.log('Was clicked!!');
    // this.state.persons[0].name = "7ossam" DON'T DO THIS!!! USE SETSTATE()

    const personIndex = this.state.persons.findIndex(p => {
      return p.id === id;
    });

    const person = { ...this.state.persons[personIndex] };

    person.name = event.target.value;

    const persons = [...this.state.persons];
    persons[personIndex] = person;

    this.setState({
      persons: persons
    });
  };

  togglePersonsHanddler = () => {
    const doesShow = this.state.ShowPersons;
    this.setState({ ShowPersons: !doesShow });
  };

  render() {
    const style = {
      backgroundColor: "green",
      color: "white",
      font: "inherit",
      border: "1px solid",
      cursor: "pointer",
      ":hover": {
        backgroundColor: "lightgreen",
        color: "black"
      }
    };

    let persons = null;

    if (this.state.ShowPersons) {
      persons = (
        <div>
          {this.state.persons.map((person, index) => {
            return (
              <Person
                name={person.name}
                age={person.age}
                click={() => this.deletePersonHandler(index)}
                key={person.id}
                changedName={(event: any) =>
                  this.nameChangeHandler(event, person.id)
                }
              />
            );
          })}
        </div>
      );
      style.backgroundColor = "red";
      style[":hover"] = {
        backgroundColor: "salmon",
        color: "black"
      };
    }

    let classes = [];

    if (this.state.persons.length <= 2) {
      classes.push("red");
    }
    if (this.state.persons.length <= 1) {
      classes.push("bold");
    }

    return (
      <StyleRoot>
        <div className="App">
          <br />
          <p className={classes.join(" ")}>Yasta garab el hoba hoba</p>
          <button style={style} onClick={this.togglePersonsHanddler}>
            Toggle Names
          </button>

          <br />
          <h1>Hello, this is sam!</h1>
          {persons}
        </div>
      </StyleRoot>
    );
  }
}

export default Radium(App);

And here is the Person Component:

import React, { Component } from "react";
import Radium from "radium";
import "./Person.css";

interface IPersonProps {
  name: string;
  age: number;
  click?: any;
  changedName?: any;
}

class Person extends Component<IPersonProps> {
  render() {
    const style = {
      "@media (min-width: 500px)": {
        width: "450px"
      }
    };
    return (
      <div className="Person">
        {" "}
        style={style}
        <p onClick={this.props.click}>
          {" "}
          I am {this.props.name} and I am {this.props.age} years old
        </p>
        <p>{this.props.children}</p>
        <input
          type="text"
          onChange={this.props.changedName}
          value={this.props.name}
        />
      </div>
    );
  }
}

export default Radium(Person);

Here is the radium package in package-lock.json:

 "@types/radium": {
      "version": "0.24.2",
      "resolved": "https://registry.npmjs.org/@types/radium/-/radium-0.24.2.tgz",
      "integrity": "sha512-AudCpKQH/csx6eB4OZhEdKf8Avm18wX8gLOig5H5iocPDPp3GRUPkQmUOXvsIYO64LyAb4CiIfSmcWUaUdvl4A==",
      "requires": {
        "@types/react": "*"
      }
    },

I am assuming that the issue is with StyleRoot isn't imported correctly somehow, but I would appreciate some input. I am also Using TypeScript

1

There are 1 answers

0
Ícaro de Barros On

I had the same problem. I managed to solve by making the typing of the constant style explicit.

const style: Radium.StyleRules = {
    '@media (min-width: 500px)': {
        width: '450px'
    }
};