简体   繁体   English

物化输入不会触发 React 中的 onChange?

[英]Materialize inputs not triggering onChange in React?

I have a Materialize input like so:我有一个 Materialize 输入,如下所示:

<input type="date" className="datepicker" onChange={this.props.handleChange} />

It is being correctly initialised by Materialize, but not firing onChange when the value of the datepicker changes.它由 Materialise 正确初始化,但在日期选择器的值更改时不会触发 onChange。 What am I doing wrong here?我在这里做错了什么? This problem seems to extend to all Materialize inputs.这个问题似乎扩展到所有 Materialise 输入。

I'm pretty sure this solves the caveat if you put it in your componentDidMount component.如果你把它放在你的 componentDidMount 组件中,我很确定这解决了这个问题。 If the select is to be re-rendered on state change, this should as well be put in componentDidUpdate如果要在状态更改时重新渲染选择,也应该将其放入 componentDidUpdate

// find the select element by its ref
const el = ReactDOM.findDOMNode(this.refs.ref_to_my_select);
// initialize the select
$('select').material_select();
// register a method to fireup whenever the select changes
$(el).on('change', this.handleInputChange)

To get the value of the datepicker in materialize they provide an onSelect option when initialising the component:为了在实现中获取 datepicker 的值,它们在初始化组件时提供了一个onSelect选项:

var instances = M.Datepicker.init(
      elems,
      {
        onSelect:function(){
          date = instances[0].date;
          console.log(date);
        }
      }
    );

https://codepen.io/doughballs/pen/dyopgpa https://codepen.io/doughballs/pen/dyopgpa

Every time you pick a date, onSelect fires, in this case console.logging the chosen date.每次选择日期时,onSelect 都会触发,在本例中为 console.logging 所选日期。

When you close the datepicker (which is actually a modal), that's when the onChange fires, in this case logging 'onChange triggered' to the console.当您关闭日期选择器(实际上是一个模态)时,就会触发 onChange,在这种情况下,将“onChange 触发”记录到控制台。

that's my solution.这就是我的解决方案。 I use useRef hook, to identify datepicker input and when onClose is fired, we can capture the object and data value, through ref var.我使用 useRef 钩子来识别 datepicker 输入,当 onClose 被触发时,我们可以通过 ref var 捕获对象和数据值。

import React, { useEffect, useState, useRef } from "react";
import M from "materialize-css";

export default function App() {

  const fromref = useRef(null); //create reference

  const [date, setDate] = useState({ fromdate: "" });

  const { fromdate } = date;

  useEffect(() => {
    let elem = document.querySelectorAll(".datepicker");
    M.Datepicker.init(elem, {
      firstDay: true,
      format: "yyyy-mm-dd",
      onClose: function() { // when onclose datepicker, we can get the value and data through the ref
        console.log(fromref.current.name, fromref.current.value);
        setDate({ [fromref.current.name]: fromref.current.value });
      }
    });
  }, []);

  return (
    <form class="col s12">
      <div class="row">
        <div class="input-field col s12">
          <input
            name="fromdate"
            type="text"
            class="datepicker"
            placeholder="from date"
            ref={fromref} //set reference to the input
          />
        </div>
      </div>
    </form>
  );
}

On componentDidUpdate() using a prop idcomponentDidUpdate() 上使用 prop id

var elem = document.getElementById('date');
        M.Datepicker.init(elem,{
            onClose:()=>{
                this.state.date = elem.value;                    
                this.setState(this.state)
            }
        });

If you want to get the value or other attributes you can access them from instaces variable when initialized and then check before submitting your form .如果您想获取或其他属性,您可以在初始化时从instaces变量访问它们,然后在提交表单之前进行检查。

var elems = document.querySelectorAll('.timepicker');
var instances = M.Timepicker.init(elems);

Then in order to get your value before submitting your form can do as follow:然后为了在提交表单之前获得您的价值,可以执行以下操作:

var date = instances[0].el.value;

There are two things which might be stopping the execution of expected behaviour.有两件事可能会阻止预期行为的执行。


  1. If the code which you have displayed question section is from rendered html tree, then onchnage assigment needs to be called while assignment itself.如果您显示问题部分的代码来自渲染的 html 树,则需要在分配时调用 onchnage 分配。
 <input type="date" className="datepicker" onChange=this.props.handleChange(event)/>
  • Note: Previously browser events use to expects event callback handlers in string format as a value.注意:以前浏览器事件使用字符串格式的事件回调处理程序作为值。


It looks like you're using materialize directly in your post but if it is possible, you could try using react-materialize as it wraps all the materialize components such that it's easier to use with React.看起来您在帖子中直接使用了 materialize,但如果可能的话,您可以尝试使用react-materialize因为它包装了所有 materialize 组件,以便更容易与 React 一起使用。 Using react-materialize would probably be the cleanest way to handle state and event changes as they provide a convenience wrapper around each materialize component.使用react-materialize可能是处理状态和事件更改的最干净的方法,因为它们为每个 materialize 组件提供了一个方便的包装器。

When using the date picker from react-materialize , you'll need to pass the handleChange method into the options prop like so:使用react-materialize的日期选择器时,您需要将handleChange方法传递到 options 道具中,如下所示:

<DatePicker
  options={{
    ...,
    onSelect: this.props.handleChange
  }}
 />

In the case of using the materialize date picker independently, if you could provide more details on how you're initializing the date picker input, I could provide a more relevant answer.在独立使用具体化日期选择器的情况下,如果您可以提供有关如何初始化日期选择器输入的更多详细信息,我可以提供更相关的答案。 But I'll give it a shot in the dark.但我会在黑暗中试一试。

From the materialize docs it looks like you'll also have to pass back some options when you initialize it to handle a callback function when a date is selected.从具体化文档看来,当您初始化它以在选择日期时处理回调函数时,您还必须传回一些选项。

I've added a JSFiddle that has a working example as well as a code snippet below, notice that when you select a date, 'hello world' is logged in the console, and the date is the first argument passed into the callback.我添加了一个 JSFiddle,它有一个工作示例以及下面的代码片段,注意当你选择一个日期时,'hello world' 被记录在控制台中,日期是传递给回调的第一个参数。

class Datepicker extends React.Component {
  constructor(props) {
    super(props)
  }

  handleChange(date) {
    console.log('hello world', date);
  }

  componentDidMount() {
      var elems = document.querySelectorAll('.datepicker');
      var instances = M.Datepicker.init(elems, {
        onSelect: this.handleChange
      });
  }

  render() {
    return (
        <div>
          <input type="text" className="datepicker" />
        </div>
    )
  }
}

Live Example Fiddle现场示例小提琴

So to answer your question of how to handle events and setting the state, you just need to pass your handleChange method into the provided options configs depending on how you're using materialize date picker.因此,要回答关于如何处理事件和设置状态的问题,您只需要根据您使用具体化日期选择器的方式将handleChange方法传递到提供的选项配置中。 In regards to integrating with a form, you could use the other callback hooks like onClose to do form validation.关于与表单集成,您可以使用其他回调钩子(如 onClose)来进行表单验证。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM