Although D3.js is a handy visualization tool, the goal of this project is to display a map of the US using SVG and React without the need for D3.

One of the most crucial aspects of this map is a complex JSON file that describes the shape of every state. Using existing source data from bl.ocks.org user Pasha as a template, I created my own states.json file which you are free to use as you like. This entire project is modeled on the demo from Pasha.

A very simple incarnation of a React SVG map of the U.S.A. could look like this.

// This is a React functional component
function USMap(props) {
    return (
        <svg viewBox="0 0 960 600">
            {props.statesData.map((stateData, index) =>
                <path
                    className="someCSSClass"
                    style={{cursor: "pointer", fill: "orange"}}
                    key={index}
                    stroke="#fff"
                    strokeWidth="6px"
                    d={stateData.shape}
                    onMouseOver={(event) => {
                        event.target.style.fill = 'red'
                    }}
                    onMouseOut={(event) => {
                        event.target.style.fill = 'orange'
                    }}
                >
                </path>
            )}
        </svg>
    )
}

class App extends React.Component {
    state = { statesData: null }

    constructor(props) {
        super(props)
        this.loadData()
    }

    async loadData() {
        const res = await fetch('https://willhaley.com/assets/united-states-map-react/states.json')
        const statesData = await res.json()
        this.setState({ statesData })
    }

    render() {
        if (this.state.statesData === null) {
            return <div>Loading...</div>
        }
        return <USMap statesData={this.state.statesData} />
    }
}

ReactDOM.render(
    <App />,
    document.getElementById('demo')
)

I find that using React to manually generate SVG is far more readable and much simpler than the D3 jQuery-selector based API, but that’s just me! Note that this is only using vanilla SVG and React, and there is plenty of room for customization with standard event handlers and JS. No other third party libraries required!

Note: This demo is loaded with React DOM and is not optimized for performance. See page source for details