Style selector for dynamic drop-down menus

import React, { Component } from "react";

export default class FontChanger extends Component{

    constructor(props){
        super(props);
        this.state ={
            selectedFont: "",
            currentFont: "",
        };
        this.handleFontChange = this.handleFontChange.bind(this);
        this.handleSubmit = this.handleSubmit.bind(this);
    }

    handleFontChange(event){
        this.setState({
            currentFont: event.target.selectedFont,
            selectedFont: this.state.value
        });
    }

    handleSubmit(event) {
        event.preventDefault();
        this.setState({ currentFont: this.state.selectedFont });
    }

    render() {
        return(
            <div>
                <form onSubmit={this.handleSubmit}>
                    <h1 style={{fontFamily: this.state.currentFont }}>Yuh Yeet</h1>
                    <select onChange={this.handleFontChange}>
                        <option value="Anton">Anton</option>
                        <option value="Calistoga">Calistoga</option>
                        <option value="Fira Sans">Fira Sans</option>
                        <option value="Noto Serif">Noto Serif</option>
                        <option value="Quicksand">Quicksand</option>
                        <option value="Ubuntu">Ubuntu</option>
                        <option value="Times New Roman">Times New Roman</option>
                        <option value="Titillium Web">Titillium Web</option>
                    </select>
                    <button type="submit"> Change </button>
                </form>
            </div>
        )
    }
}

I'm having trouble changing the inline style of the h1 tag with a font selected from my dropdown menu. I've imported all fonts into my index.html from Google Fonts, so that shouldn't be an issue. Could it be an error in how I'm using setState or accessing the state values?

Answer №1

The following code functions properly. Here are a couple of points to note:

  • It is correct that the onSubmit handler is not necessary as mentioned by Taki. However, if you do not use it, the font will change as soon as it is selected, rather than when the "change" button is clicked. Additionally, in Taki's solution, the fontHandler function would not provide the expected result in setting the state. If that function was utilized, the state would need to be set to current: value.target.value
  • When using the setState(), there are two considerations. 1 - Refrain from referencing the current state; instead, use prevState. State updates are sometimes grouped together, leading to potential errors. 2 - Avoid referencing the eventHandler for two reasons. Firstly, it may not recognize what you are referring to. onChange and onSubmit are not functions defined within your component, but rather attributes to <form> and select respectively. Secondly, it is best practice not to reference functions within the state. Create the function outside of the state object and call it to set the desired state changes.
  • I have initialized the state with the first select option. This won't impact the functionality of your app, but it will enhance the user experience if the default font is not set to Anton.

Furthermore, consider exploring Hooks and Arrow functions. They can simplify your work and streamline your code.

I trust this breakdown sheds light on why your code may not be functioning as intended. Yeet yeet.

export default class Fonts extends Component {
  constructor(props) {
    super(props);
    this.state = {
      selectedFont: "Anton",
      displayedFont: "Anton"
    };
    this.fontHandler = this.fontHandler.bind(this);
    this.handleSubmit = this.handleSubmit.bind(this);
  }

  fontHandler(event) {
    const font = event.target.value;

    this.setState({
      selectedFont: font
    });
  }

  handleSubmit(event) {
    event.preventDefault();

    this.setState(prevState => ({
      displayedFont: prevState.selectedFont
    }));
  }

  render() {
    return (
      <div>
        {console.log(this.state)}
        <form onSubmit={this.handleSubmit}>
          <h1 style={{ fontFamily: this.state.displayedFont }}>Yuh Yeet</h1>
          <select onChange={this.fontHandler}>
            <option value="Anton">Anton</option>
            <option value="Calistoga">Calistoga</option>
            <option value="Fira Sans">Fira Sans</option>
            <option value="Noto Serif">Noto Serif</option>
            <option value="Quicksand">Quicksand</option>
            <option value="Ubuntu">Ubuntu</option>
            <option value="Times New Roman">Times New Roman</option>
            <option value="Titillium Web">Titillium Web</option>
          </select>
          <button type="submit"> Change </button>
        </form>
      </div>
    );
  }
}

Answer №2

Your code has a few issues that need addressing. The select element's onChange attribute should point to the function fontHandler, which will update the state to set the value of current:

<select onChange={this.fontHandler}>
  // ...
</select>

The fontHandler function should look like this:

fontHandler(value){
  this.setState({      
      current: value
  });
}

No need to submit the form.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Expanding the last row to ensure its proper width with flex-grow

I have a flexbox with columns that each take up one third of the width. However, due to using flex-grow, the last element does not stick to its column size. I understand why this is happening, but I don't want to use max-width as it's not always ...

Processing made easy with jQuery

In my HTML page, I have multiple rows that represent records from a database. Each row contains input fields and a link at the end. When I click on the link, I need to capture the values of the input fields within the same row. Here is an example of the H ...

Having difficulty showcasing API call results in a Vue.js component

I am currently experimenting with Vue.js in an attempt to showcase results from a Wikipedia API call within a component using the v-for directive. However, I seem to be encountering some backend issues that I cannot pinpoint. To access the jsFiddle link, ...

What is the best way to show the initial 20 words on the screen, followed by the next 20 words using

Within a single tag, I have a string as shown in the example below. My goal is to display the first 20-25 words on screen, then continue with the next set of words, and so forth. Once 20 words are displayed, the remaining text should be hidden. <p>Lo ...

Set default values for input fields based on selected options in php and mysql

I need help creating a form that will submit details when an option is selected from a database. The MySQL table has the following fields under USERS : [email], [age], [name]. I want to automatically fill in the values of other input fields when a user s ...

What are some strategies I can use to prevent issues with my web design while updating bootstrap?

I recently updated Bootstrap CDN from version 4.0.0 alpha to beta this morning. Here is a snapshot of how the web page looked before (still under construction): Website with Bootstrap 4.0.0 alpha And here is how it appears now: With Bootstrap 4.0.0 bet ...

Vue component failing to display data passed as props

As a Vue beginner, I ventured into creating a custom component and attempted to bind everything just like in the basic Vue CLI template. Here is my code snippet. Circle.vue <template> <div :style="custom"> </div> </template&g ...

Next.js encountered a surprising conclusion to the JSON input

After retrieving data from /api/notes/1, the following JSON object is received: { "id":1, "author":1, "title":"First Note", "excerpt":"Just a note, blah blah blah", "body":"First no ...

Setting up an i18n project in AngularJS

I just embarked on my angularjs journey yesterday with little to no prior knowledge about it. My initial goal is to centralize all the labels for my UI in a file (to facilitate swapping them out for i18n). As far as I know, this can be achieved by importi ...

Utilize the Google Maps API to align an SVG symbol with the direction of an aircraft's

I have been struggling to update the rotation of the Google Maps API SVG aircraft symbol to display the correct heading as it moves. Although it initially loads with the correct heading, I can't seem to figure out how to dynamically update it. I' ...

Creating dynamic CSS in .Net Core using Tag Helpers instead of inline styles

Is there a method to dynamically insert CSS into the stylesheet without using inline HTML with TagHelpers? While SetHtmlContent generates dynamic HTML, is there a similar method for CSS? It's commonly recommended to keep CSS and HTML files separate. ...

How can I make the columns in Next.js / Tailwind expand horizontally first instead of vertically?

Recently, I decided to customize the Next.js Image Gallery starter for some hands-on experience in full stack development with Next.js. My goal was to create a chronological photo gallery of a recent trip, but encountered an issue where the responsive colu ...

Converting a string to a JSON array with Jackson in RESTful APIs

As I delve into the world of JSON and REST, I find myself testing a REST API that returns strings in the following format: [{ "Supervisor_UniqueName": "adavis", "Active": "true", "DefaultCurrency_UniqueName": "USD", "arches_type": "x-zensa ...

JavaScript - issue with event relatedTarget not functioning properly when using onClick

I encountered an issue while using event.relatedTarget for onClick events, as it gives an error, but surprisingly works fine for onMouseout. Below is the code snippet causing the problem: <html> <head> <style type="text/css"> ...

What is the best way to make an HTML table with a static header and a scrollable body?

Is there a way to keep the table header fixed while allowing the table body to scroll in an HTML table? Any advice on how to achieve this would be greatly appreciated. Thanks in advance! ...

Enhance user experience by implementing a feature in AngularJS that highlights anchor

As I am in the process of developing a chat application using Angular, I have encountered an issue with switching between views. One view, named 'chat.html', displays the list of available users while another view, 'chatMessages.html', ...

FullCalendar jQuery caught in an endless loop

After successfully implementing drag and drop deletion, I encountered a new issue. Whenever I delete an event, the removal process functions properly but then the code gets stuck in a loop within the eventDragStop function causing the calendar to freeze ...

Tips for effectively highlighting search text within HTML content without causing any issues

I am in search of a solution that can assist me in searching for specific terms within an HTML string while also highlighting them. I have the ability to remove the HTML content from the string, but this poses the problem of losing the context of the origi ...

Tips for transferring an MVC model to a UI-bootstrap modal

Trying to implement an Angular/bootstrap modal for editing MVC ApplicationUser scaffolded views. Came across jquery examples but want to stick with angular-ui or plain bootstrap for consistency in modals. Unclear on how the MVC controller is being called f ...

"One specific div in Safari is having trouble with the external stylesheet, while the other divs are functioning properly- any

I'm facing a puzzling issue that has me stumped. I'm working on a website and have a simple footer with a link at the bottom: <div id="sitefooter"> <a href="#">This is the link</a> </div> My stylesheet includes styling f ...